813b312001-06-25Honza Petrous /*
7143a22001-08-17Honza Petrous  * $Id: snmpagent.pike,v 1.9 2001/08/17 00:01:11 hop Exp $
813b312001-06-25Honza Petrous  * * The Roxen SNMP agent * Copyright © 2001, Roxen IS. * * Author: Honza Petrous * January 2001
14cf2b2001-07-18Honza Petrous RFC 1213 base MIB system.* (all done) snmp.* (all done, but most of them all still death) Future: RFC 1215 Convention for defining traps RFC 1227 SNMP MUX procotol and MIB
813b312001-06-25Honza Petrous RFC 2248 Network Services Monitoring MIB
14cf2b2001-07-18Honza Petrous RFC 2576 Coexistence between v1, v2 and v3 of SNMP protocol RFC 2594 Definitions of managed objects for WWW services
813b312001-06-25Honza Petrous  Developer notes: Known issues: - every reload spawne a new thread, I guess that old ones are never
6897c92001-06-27Honza Petrous  used then. [threads leak] // FIXME: solved by switching to the async i/o
14cf2b2001-07-18Honza Petrous  - the OID must be minimally 5 elements long, otherwise GETNEXT return "no such name" error
6f669a2001-08-14Honza Petrous  - default value for snmpagent host/port variable in the config. int. hasn't set correctly hostname part // FIXME: how reach config.int.'s URL from define_global_variables ?
7e89ce2001-08-15Honza Petrous  - cold_start trap code isn't completed
7143a22001-08-17Honza Petrous  - tabular walking throught roxenis.app.roxen.* doesn't working
813b312001-06-25Honza Petrous  Todos: v1.0 todo: - cold/warm start trap generation
7143a22001-08-17Honza Petrous  - restart/stop
813b312001-06-25Honza Petrous  - 'basic' Roxen working variables v1.1 todo: - trap handling
7143a22001-08-17Honza Petrous  - module reloading
813b312001-06-25Honza Petrous  v2.0 todo: - Roxen.module API for registering MIB subtree v3.0 todo: - SNMP v3 - security */ inherit "global_variables"; inherit Roxen; #define roxen roxenp()
14cf2b2001-07-18Honza Petrous // FIXME: thread leaking is hiden by moving to the async i/o model
813b312001-06-25Honza Petrous //#define NO_THREADS !constant(thread_create) #define NO_THREADS 1 #ifdef SNMPAGENT_DEBUG # define SNMPAGENT_MSG(X) report_notice("SNMPagent: "+X+"\n") # define SNMPAGENT_MSGS(X, Y) report_notice("SNMPagent: "+X+"\n", @Y) #else # define SNMPAGENT_MSG(X) # define SNMPAGENT_MSGS(X, Y) #endif
6f669a2001-08-14Honza Petrous //! Default port number for agent #ifndef SNMPAGENT_DEFAULT_PORT #define SNMPAGENT_DEFAULT_PORT 1610 #endif
813b312001-06-25Honza Petrous #define SNMP_OP_GETREQUEST 0 #define SNMP_OP_GETNEXT 1 #define SNMP_OP_GETRESPONSE 2 #define SNMP_OP_SETREQUEST 3 #define SNMP_OP_TRAP 4
14cf2b2001-07-18Honza Petrous #define OBJ_STR(x) ({"str", x}) #define OBJ_INT(x) ({"int", x}) #define OBJ_OID(x) ({"oid", x}) #define OBJ_TICK(x) ({"tick", x}) #define OBJ_COUNT(x) ({"count", x}) //! The starting part of OID of every object will have, so we stripp it out //! before making index from OID to the MIB DB
7143a22001-08-17Honza Petrous #define MIBTREE_BASE "1.3.6.1" #define RISMIB_BASE_ADD "4.1.8614" // enterprises.roxenis #define RISMIB_BASE MIBTREE_BASE+"."+RISMIB_BASE_ADD #define RISMIB_BASE_WEBSERVER_ADD "1.1" // enterprises.roxenis.app.roxen #define RISMIB_BASE_WEBSERVER RISMIB_BASE+"."+RISMIB_BASE_WEBSERVER_ADD // enterprises.roxenis.app.roxen.global #define RISMIB_BASE_WEBSERVER_GLOBAL RISMIB_BASE_WEBSERVER+".1" // enterprises.roxenis.app.roxen.global.vs #define RISMIB_BASE_WEBSERVER_GLOBAL_VS RISMIB_BASE_WEBSERVER_GLOBAL+".1" // enterprises.roxenis.app.roxen.vs #define RISMIB_BASE_WEBSERVER_VS RISMIB_BASE_WEBSERVER+".2" // enterprises.roxenis.app.roxen.vs.name #define RISMIB_BASE_WEBSERVER_VS_NAME RISMIB_BASE_WEBSERVER_VS+".1" // enterprises.roxenis.app.roxen.vs.sentdata #define RISMIB_BASE_WEBSERVER_VS_SDATA RISMIB_BASE_WEBSERVER_VS+".2" // enterprises.roxenis.app.roxen.vs.senthdrs #define RISMIB_BASE_WEBSERVER_VS_SHDRS RISMIB_BASE_WEBSERVER_VS+".3" // enterprises.roxenis.app.roxen.vs.recvdata #define RISMIB_BASE_WEBSERVER_VS_RDATA RISMIB_BASE_WEBSERVER_VS+".4" // enterprises.roxenis.app.roxen.vs.requests #define RISMIB_BASE_WEBSERVER_VS_REQS RISMIB_BASE_WEBSERVER_VS+".5"
813b312001-06-25Honza Petrous 
14cf2b2001-07-18Honza Petrous #define LOG_EVENT(txt, pkt) log_event(txt, pkt)
813b312001-06-25Honza Petrous  class SNMPagent { private int enabled; // Global variables private object fd; // opened UDP port private int inited; // flag private int snmpinpkts; private int snmpoutpkts;
e427912001-06-30Honza Petrous  private int snmpbadver; private int snmpbadcommnames; private int snmpbadcommuses;
2db8322001-07-01Honza Petrous  private int snmpenaauth;
813b312001-06-25Honza Petrous  private mapping events; private mixed co; private object th;
14cf2b2001-07-18Honza Petrous  private static object mib; private mapping vsdb;
e427912001-06-30Honza Petrous 
14cf2b2001-07-18Honza Petrous  array get_snmpinpkts() { return OBJ_COUNT(snmpinpkts); }; array get_snmpoutpkts() { return OBJ_COUNT(snmpoutpkts); }; array get_snmpbadver() { return OBJ_COUNT(snmpbadver); }; array get_snmpbadcommnames() { return OBJ_COUNT(snmpbadcommnames); }; array get_snmpbadcommuses() { return OBJ_COUNT(snmpbadcommuses); };
7143a22001-08-17Honza Petrous  array get_snmpenaauth() { return OBJ_INT(snmpenaauth); };
813b312001-06-25Honza Petrous 
14cf2b2001-07-18Honza Petrous  array get_virtserv() { return OBJ_COUNT(sizeof(vsdb)); };
813b312001-06-25Honza Petrous 
e427912001-06-30Honza Petrous 
813b312001-06-25Honza Petrous  void create() {
14cf2b2001-07-18Honza Petrous  vsdb = ([]);
813b312001-06-25Honza Petrous  //disable(); } //! Enable SNMPagent processing.
14cf2b2001-07-18Honza Petrous  int enable() {
813b312001-06-25Honza Petrous 
6f669a2001-08-14Honza Petrous  if(enabled) return(enabled);
7e89ce2001-08-15Honza Petrous  mib = SubMIBSystem(); // system.* table
12e6ea2001-07-19Honza Petrous  if(objectp(mib)) { // snmp.*
7143a22001-08-17Honza Petrous  mib->register(SubMIBSnmp(this_object()));
12e6ea2001-07-19Honza Petrous  // enterprises.roxenis.*
7143a22001-08-17Honza Petrous  mib->register(SubMIBRoxenVS(this_object())); mib->register(SubMIBRoxenVSName(this_object()));
12e6ea2001-07-19Honza Petrous  }
813b312001-06-25Honza Petrous  if (!status()) start(); enabled = 1; return (enabled); } //! Disable SNMPagent processing.
14cf2b2001-07-18Honza Petrous  int disable() {
813b312001-06-25Honza Petrous  if(status()) stop(); enabled = 0; return (!enabled); } int status() { return enabled; } private void log_event(string txt, mapping pkt) { SNMPAGENT_MSG(sprintf("event: %O", txt)); if(zero_type(events[txt])) events[txt] += ([ pkt->ip : ([ pkt->community: 1]) ]) ; else if(zero_type(events[txt][pkt->ip])) events[txt][pkt->ip] += ([ pkt->community: 1]); else events[txt][pkt->ip][pkt->community]++; } //! Check access aginst snmp_community array.
14cf2b2001-07-18Honza Petrous  private int chk_access(string level /*, string attrname*/, mapping pkt) {
813b312001-06-25Honza Petrous  return (search(query("snmp_community"), pkt->community+":"+level) > -1) || (search(query("snmp_community"), pkt->community+":"+"rw") > -1); } //! The main code of SNMPagent.
14cf2b2001-07-18Honza Petrous  private void process_query(mapping data) {
813b312001-06-25Honza Petrous  mapping pdata, rdata = ([]); int msgid, op, errnum = 0, setflg = 0; string attrname, comm; array val; snmpinpkts++; pdata = fd->decode_asn1_msg(data);
6f669a2001-08-14Honza Petrous  //SNMPAGENT_MSG(sprintf("Got parsed: %O", pdata));
813b312001-06-25Honza Petrous  if(!mappingp(pdata)) { SNMPAGENT_MSG("SNMP message can not be decoded. Silently ommited."); return; } msgid = indices(pdata)[0]; comm = pdata[msgid]->community || ""; op = pdata[msgid]->op; // test for correct community string if(!chk_access("ro", pdata[msgid])) {
e427912001-06-30Honza Petrous  snmpbadcommnames++;
813b312001-06-25Honza Petrous  errnum = 5 /*SNMP_ERR_GENERR*/; attrname = indices(pdata[msgid]->attribute[0])[0]; LOG_EVENT("Bad community name", pdata[msgid]); } else foreach(pdata[msgid]->attribute, mapping attrs) { mixed attrval = values(attrs)[0]; attrname = indices(attrs)[0];
14cf2b2001-07-18Honza Petrous  if(!mib) { SNMPAGENT_MSG(" MIB table isn't loaded!\n"); // what to do now ? } switch(op) {
813b312001-06-25Honza Petrous  case SNMP_OP_GETREQUEST:
14cf2b2001-07-18Honza Petrous  val = mib->get(attrname, pdata[msgid]);
7e89ce2001-08-15Honza Petrous  if (arrayp(val) && sizeof(val) && val[0])
14cf2b2001-07-18Honza Petrous  rdata[attrname] += val;
813b312001-06-25Honza Petrous  break; case SNMP_OP_GETNEXT:
14cf2b2001-07-18Honza Petrous  val = mib->getnext(attrname, pdata[msgid]);
7e89ce2001-08-15Honza Petrous  if (arrayp(val) && sizeof(val) && val[0])
14cf2b2001-07-18Honza Petrous  //rdata[attrname] += val; rdata[val[0]] += val[1..2];
813b312001-06-25Honza Petrous  break; case SNMP_OP_SETREQUEST:
14cf2b2001-07-18Honza Petrous  val = mib->set(attrname, attrval, pdata[msgid]);
7e89ce2001-08-15Honza Petrous  if(arrayp(val) && sizeof(val))
14cf2b2001-07-18Honza Petrous  setflg = val[0]; //rdata[attrname] += ({ "int", attrval }); rdata["1.3.6.1.2.1.1.3.0"] += ({"tick", get_uptime() }); if (arrayp(val) && stringp(val[1])) report_warning(val[1]); break;
813b312001-06-25Honza Petrous 
2db8322001-07-01Honza Petrous  } //switch
14cf2b2001-07-18Honza Petrous  //else // SNMPAGENT_MSG(sprintf(" unknown or unsupported OID: %O:%O", attrname, attrval));
813b312001-06-25Honza Petrous  } //foreach if(op == SNMP_OP_SETREQUEST && !setflg && !errnum) { LOG_EVENT("Set not allowed", pdata[msgid]);
14cf2b2001-07-18Honza Petrous  snmpbadcommuses++;
813b312001-06-25Honza Petrous  } //SNMPAGENT_MSG(sprintf("Answer: %O", rdata)); snmpoutpkts++; if(!sizeof(rdata)) { if (!errnum) LOG_EVENT("No such name", pdata[msgid]); fd->get_response(([attrname:({"oid", attrname})]), pdata, errnum || 2 /*SNMP_NOSUCHNAME*/); } else fd->get_response(rdata, pdata); }
6f669a2001-08-14Honza Petrous  //! Returns domain name of the config. int. virtual server private string get_cif_domain() { return(Standards.URI(roxen->configurations[0]->get_url()||"http://0.0.0.0")->host); }
813b312001-06-25Honza Petrous  //! Opens the SNMP port. Then waits for the requests.
14cf2b2001-07-18Honza Petrous  private void real_start() {
813b312001-06-25Honza Petrous  mixed err; mapping data; array hp = query("snmp_hostport")/":";
6f669a2001-08-14Honza Petrous  int p = (sizeof(hp)>1) ? (int)hp[1] : (int)SNMPAGENT_DEFAULT_PORT;
813b312001-06-25Honza Petrous 
6f669a2001-08-14Honza Petrous  if(!sizeof(hp[0])) hp[0] = get_cif_domain();
14cf2b2001-07-18Honza Petrous  err = catch( fd = Protocols.SNMP.protocol(0, hp[0], p||161) );
813b312001-06-25Honza Petrous  if(arrayp(err)) RXML.run_error("SNMPagent: can't open UDP port " + hp[0]+":"+(string)(p||161)+"[" + err[0] + "]."); SNMPAGENT_MSG(sprintf("SNMP UDP port %s:%d binded successfully.", hp[0], p||161)); enabled = 1; #if NO_THREADS // set callbacks fd->set_nonblocking(process_query); #else // wait for connection //while(1) process_query(fd->read()); while(enabled) if(!arrayp(err=catch(data=fd->read()))) process_query(data); #endif }
14cf2b2001-07-18Honza Petrous  //! Starts SNMP agent by calling real_start method
813b312001-06-25Honza Petrous  private void start() { events = ([]); if(!inited) { inited++; SNMPAGENT_MSG("Initializing..."); //fd = Stdio.UDP(); //Port(); #if NO_THREADS
6897c92001-06-27Honza Petrous  //SNMPAGENT_MSG("Threads don't detected. Async I/O used intstead.");
813b312001-06-25Honza Petrous  co = call_out( real_start, 1 ); #else
6897c92001-06-27Honza Petrous  //SNMPAGENT_MSG("Threads detected. One thread will be created for agent processing.");
813b312001-06-25Honza Petrous  th = thread_create( real_start ); #endif } }
14cf2b2001-07-18Honza Petrous  //! Stops processing of SNMP agent by cleaning all internal objects
813b312001-06-25Honza Petrous  void stop() { SNMPAGENT_MSG("Shutting down..."); fd->set_read_callback(0); catch(fd->set_blocking()); catch(fd->close()); #if NO_THREADS remove_call_out(co); #else th = 0; #endif
6897c92001-06-27Honza Petrous  destruct(fd); // avoid fd leaking; FIXME: some cyclic dependencies in SNMP pmod.
813b312001-06-25Honza Petrous  fd = 0; inited = 0; SNMPAGENT_MSG("Shutdown complete."); }
14cf2b2001-07-18Honza Petrous  //! Cold start notificator. Sends trap for all virtual servers in the vsarr. void coldstart_trap(array(int) vsarr) { object uri; if(intp(vsarr)) return; foreach(vsarr, int vsid)
7e89ce2001-08-15Honza Petrous  if(vsdb[vsid] && vsdb[vsid]->variables["snmp_traphosts"] && sizeof(vsdb[vsid]->variables["snmp_traphosts"]->query())) { SNMPAGENT_MSG(sprintf("server %O(#%d): traphosts:%O", vsdb[vsid]->name, vsid,
6f669a2001-08-14Honza Petrous  vsdb[vsid]->variables["snmp_traphosts"]->query())); foreach(vsdb[vsid]->variables["snmp_traphosts"]->query(), mixed thost) {
14cf2b2001-07-18Honza Petrous  uri = Standards.URI(thost);
7e89ce2001-08-15Honza Petrous  SNMPAGENT_MSG(sprintf("Trap sent: %s", thost));
6f669a2001-08-14Honza Petrous /* fd->trap( ([RISMIB_BASE_WEBSERVER+".999.1.1": ({ "str", Standards.URI(vsdb[vsid]->variables["MyWorldLocation"]->query())->host}) ]), uri->host, uri->port); */
14cf2b2001-07-18Honza Petrous  } } else
12e6ea2001-07-19Honza Petrous  if(vsdb[vsid])
7e89ce2001-08-15Honza Petrous  SNMPAGENT_MSG(sprintf("server %O(#%d) hasn't any traphosts.", vsdb[vsid] && vsdb[vsid]->name, vsid));
14cf2b2001-07-18Honza Petrous  } //! Warm start notificator void warmstart_trap() {
813b312001-06-25Honza Petrous  }
14cf2b2001-07-18Honza Petrous  //! Authentication failure notificator void authfailure_trap() { } //! Enterprise specific trap notificator void enterprise_trap() { } //! Adds virtual server to the DB of managed objects int add_virtserv(int vsid) { if(zero_type(vsdb[vsid])) {
7e89ce2001-08-15Honza Petrous  report_debug(sprintf("SNMPagent: added server %O(#%d)\n", roxen->configurations[vsid]->name, vsid));
14cf2b2001-07-18Honza Petrous //report_debug(sprintf("snmpagent:DEB: %O\n",mkmapping(indices(roxen->configurations[vsid]), values(roxen->configurations[vsid])))); vsdb += ([vsid: roxen->configurations[vsid]]);
12e6ea2001-07-19Honza Petrous  }
e427912001-06-30Honza Petrous 
7143a22001-08-17Honza Petrous  // some tabulars handlers ...
e427912001-06-30Honza Petrous  return(1); }
6f669a2001-08-14Honza Petrous  //! Returns name of the virtual server string get_virtservname(int vsid) { if(zero_type(vsdb[vsid])) return 0; // bad index number return (roxen->configurations[vsid]->name); }
7143a22001-08-17Honza Petrous  //! Returns send data statistics of the virtual server int get_virtservsdata(int vsid) { if(zero_type(vsdb[vsid])) return -1; // bad index number return (roxen->configurations[vsid]->sent); } //! Returns received data statistics of the virtual server int get_virtservrdata(int vsid) { if(zero_type(vsdb[vsid])) return -1; // bad index number return (roxen->configurations[vsid]->received); } //! Returns send headers statistics of the virtual server int get_virtservshdrs(int vsid) { if(zero_type(vsdb[vsid])) return -1; // bad index number return (roxen->configurations[vsid]->hsent); } //! Returns request statistics of the virtual server int get_virtservreqs(int vsid) { if(zero_type(vsdb[vsid])) return -1; // bad index number return (roxen->configurations[vsid]->requests); }
14cf2b2001-07-18Honza Petrous  //! Deletes virtual server's specific objects from DB int del_virtserv(int vsid) { if(!zero_type(vsdb[vsid])) {
7e89ce2001-08-15Honza Petrous  report_debug(sprintf("SNMPagent: deleted server %O(#%d)\n", roxen->configurations[vsid]->name, vsid));
14cf2b2001-07-18Honza Petrous  vsdb -= ([ vsid: 0 ]); }
e427912001-06-30Honza Petrous  return(1); }
813b312001-06-25Honza Petrous } // end of SNMPagent object
14cf2b2001-07-18Honza Petrous //! Removes first four octets from OID string, as internal table works //! on such stripped OIDs. private string|int oid_strip (string oid) { // note: this method must be public! array arr = oid / "."; if (sizeof(arr) < 7) // FIXME: exists oid with less octets? return 0; oid = arr[4..] * "."; return oid; } //! //! Generic class for submib tree managers, or individual objects as well. //! class SubMIBManager { //! Name of object constant name = "generic skeleton"; //! OID number of the registered subtree constant tree = ""; //! Table of managed objects in the form: //! ([ string stripped_oid: function get_value ]) mapping submibtab = ([]); //! Table of registered subtree managers in the form: //! ([ string stripped_oid: object manager ]) mapping subtreeman = ([]); //! Checks existence of an managed object in the database private int|string oid_check(string oid) { if(!(oid = oid_strip(oid))) return 0; return zero_type(submibtab[oid]) ? 0 : oid; } //! Low level method for registering a new manager for object or the whole subtree. //! Note: If oid is ancessor of already existing oids, then autohiding of existing //! object's managers will be done. Unregistering reenabled such hided managers //! again.
7143a22001-08-17Honza Petrous  int register(object manager) { string oid = manager->tree;
14cf2b2001-07-18Honza Petrous  if(oid_check(oid))
7143a22001-08-17Honza Petrous  return 0; // false => the OID is already registered. // What about stackable organization ?
14cf2b2001-07-18Honza Petrous  if(subtreeman[oid]) return 0; // false => already registered subtreeman += ([oid: manager]); // FIXME: autohiding of subtree. Is it goood?
7143a22001-08-17Honza Petrous  SNMPAGENT_MSG(sprintf("manager %O registered for tree %O", manager->name, manager->tree));
14cf2b2001-07-18Honza Petrous  return 1; // ok (registered) } void create() { report_error("SubMIBManager object [" + (string)name + "] hasn't replaced contructor!\n"); } // create //! Returns array. First element is type of second element. //! Is usable for very primitive managed objects, in which case the value //! is got by calling function from submibtab table. //array `[](string oid) { array get(string oid, mapping|void pkt) { function rval; string soid; SNMPAGENT_MSG(sprintf("GET(%s): %O", name, oid)); soid = oid_strip(oid); if (functionp(rval = submibtab[soid])) { SNMPAGENT_MSG("found MIB object."); return rval(); } // hmm, now we have to try some of the registered managers array s = soid/".";
7143a22001-08-17Honza Petrous  for(int cnt = sizeof(s)-1; cnt>0; cnt--) { SNMPAGENT_MSG(sprintf("finding manager for tree %O", s[..cnt]*"."));
14cf2b2001-07-18Honza Petrous  if(subtreeman[s[..cnt]*"."]) { // good, subtree manager exists string manoid = s[..cnt]*"."; SNMPAGENT_MSG(sprintf("found subtree manager: %s(%O)", subtreeman[manoid]->name, manoid)); return subtreeman[manoid]->get(oid); }
7143a22001-08-17Honza Petrous  } SNMPAGENT_MSG("Not found any suitable manager"); return 0;
14cf2b2001-07-18Honza Petrous  } //! Returns array ({ nextoid, type, val }) or 0 array|int getnext(string oid, mapping|void pkt) { array(string) idxnums = Array.sort(indices(submibtab)); int idx; string soid; array s; SNMPAGENT_MSG(sprintf("GETNEXT(%s): %O", name, oid)); if(!(soid = oid_strip(oid))) return 0; idx = search(idxnums, soid); if(idx >= 0) { // good, we found equality SNMPAGENT_MSG(sprintf("%s: eq match: %O", tree, idx)); if(idx < sizeof(idxnums)-1) return (({ MIBTREE_BASE+"."+(string)idxnums[idx+1], @submibtab[idxnums[idx+1]]() })); else return 0; } else { int tlen = sizeof(tree/"."); array sarr = soid/"."; //if(soid[..(sizeof(tree)-1)] == tree) { // only inside owned subtree if(sizeof(sarr)>=tlen && (sarr[..tlen-1]*".") == tree) { SNMPAGENT_MSG(name+": owned subtree found."); // hmm, now we have to find nearest subtree for(idx = 0; idx < sizeof(idxnums); idx++) if (soid < idxnums[idx]) {
7e89ce2001-08-15Honza Petrous  SNMPAGENT_MSG(sprintf("subtree match: %O", idxnums[idx]));
14cf2b2001-07-18Honza Petrous  return (({ MIBTREE_BASE+"."+(string)idxnums[idx], @submibtab[idxnums[idx]]() })); } } SNMPAGENT_MSG(name+": foreign object detected."); s = soid/"."; // hmm, now we have to try some of the registered managers for(int cnt = sizeof(s)-1; cnt>0; cnt--) {
7143a22001-08-17Honza Petrous  SNMPAGENT_MSG(sprintf("finding manager for tree %O", s[..cnt]*"."));
14cf2b2001-07-18Honza Petrous  if(subtreeman[s[..cnt]*"."]) { // good, subtree manager exists string manoid = s[..cnt]*"."; SNMPAGENT_MSG(sprintf("found subtree manager: %s(%O)", subtreeman[manoid]->name, manoid)); return subtreeman[manoid]->getnext(oid, pkt); } } }
7143a22001-08-17Honza Petrous  SNMPAGENT_MSG("Not found any suitable manager");
14cf2b2001-07-18Honza Petrous  return 0; } //! Tries to do SET operation. array set(string oid, mixed val, mapping|void pkt) { return ({ 0, 0}); } //! Tries to guess next OID. Usable to situation when GET_NEXT op //! contains OID without .0 string|int oid_guess_next(string oid) { if(oid_check(oid+".0")) return oid+".1"; return 0; } //! External function for MIB object returning nothing array get_null() { return OBJ_COUNT(0); } } // SubMIBManager // base external feeders //! External function for MIB object 'system.sysDescr' array get_description() {
7143a22001-08-17Honza Petrous  return OBJ_STR("Roxen Webserver SNMP agent v"+("$Revision: 1.9 $"/" ")[1]+" (devel. rel.)");
14cf2b2001-07-18Honza Petrous } //! External function for MIB object 'system.sysOID' array get_sysoid() { return OBJ_OID(RISMIB_BASE_WEBSERVER); } //! External function for MIB object 'system.sysUpTime' array get_uptime() { return OBJ_TICK((time(1) - roxen->start_time)*100); } //! External function for MIB object 'system.sysContact' array get_syscontact() { return OBJ_STR(query("snmp_syscontact")); } //! External function for MIB object 'system.sysName' array get_sysname() { return OBJ_STR(query("snmp_sysname")); } //! External function for MIB object 'system.sysLocation' array get_syslocation() { return OBJ_STR(query("snmp_syslocation")); } //! External function for MIB object 'system.sysServices' array get_sysservices() { return OBJ_INT(query("snmp_sysservices")); } //! system subtree manager //! Manages the basic system.sys* submib tree.
7e89ce2001-08-15Honza Petrous class SubMIBSystem {
14cf2b2001-07-18Honza Petrous  inherit SubMIBManager; constant name = "system"; constant tree = "2.1.1"; void create() { submibtab = ([ // system "2.1.1" // system.sysDescr "2.1.1.1.0": get_description, // system.sysObjectID "2.1.1.2.0": get_sysoid, // system.sysUpTime "2.1.1.3.0": get_uptime, // system.sysContact "2.1.1.4.0": get_syscontact, // system.sysName "2.1.1.5.0": get_sysname, // system.sysLocation "2.1.1.6.0": get_syslocation, // system.sysServices "2.1.1.7.0": get_sysservices, ]); } // create } // SubMIBsystem //! snmp subtree manager //! Manages the basic snmp.snmp* submib tree.
7e89ce2001-08-15Honza Petrous class SubMIBSnmp {
14cf2b2001-07-18Honza Petrous  inherit SubMIBManager; constant name = "snmp"; constant tree = "2.1.11"; void create(object agent) { submibtab = ([ // snmp //"2.1.11": ({ 0, get_null, "2.1.11.1.0" }), // snmp.snmpInPkts "2.1.11.1.0": agent->get_snmpinpkts, // snmp.snmpOutPkts "2.1.11.2.0": agent->get_snmpoutpkts, // snmp.snmpBadVers "2.1.11.3.0": agent->get_snmpbadver, // snmp.snmpInBadCommunityNames "2.1.11.4.0": agent->get_snmpbadcommnames, // snmp.snmpInBadCommunityUses "2.1.11.5.0": get_null, // snmp.snmpInASNParseErrs "2.1.11.6.0": get_null, // 7 is not used // snmp.snmpInTooBigs "2.1.11.8.0": get_null, // snmp.snmpInNoSuchNames "2.1.11.9.0": get_null, // snmp.snmpInBadValues "2.1.11.10.0": get_null, // snmp.snmpInReadOnlys "2.1.11.11.0": get_null, // snmp.snmpInGenErrs "2.1.11.12.0": get_null, // snmp.snmpInTotalReqVars "2.1.11.13.0": get_null, // snmp.snmpInTotalSetVars "2.1.11.14.0": get_null, // snmp.snmpInGetRequests "2.1.11.15.0": get_null, // snmp.snmpInGetNexts "2.1.11.16.0": get_null, // snmp.snmpInSetRequests "2.1.11.17.0": get_null, // snmp.snmpInGetResponses "2.1.11.18.0": get_null, // snmp.snmpInTraps "2.1.11.19.0": get_null, // snmp.snmpOutTooBigs "2.1.11.20.0": get_null, // snmp.snmpOutNoSuchNames "2.1.11.21.0": get_null, // snmp.snmpOutBadValues "2.1.11.22.0": get_null, // 23 is not used // snmp.snmpOutGenErrs "2.1.11.24.0": get_null, // snmp.snmpOutGetRequests "2.1.11.25.0": get_null, // snmp.snmpOutGetNexts "2.1.11.26.0": get_null, // snmp.snmpOutSetRequests "2.1.11.27.0": get_null, // snmp.snmpOutGetResponses "2.1.11.28.0": get_null, // snmp.snmpOutTraps "2.1.11.29.0": get_null, // snmp.snmpEnableAuthenTraps "2.1.11.30.0": agent->get_snmpenaauth, ]); } }
12e6ea2001-07-19Honza Petrous //! roxenis enterprise subtree manager //! Manages the enterprise.roxenis.* submib tree.
7143a22001-08-17Honza Petrous class SubMIBRoxenVS {
12e6ea2001-07-19Honza Petrous  inherit SubMIBManager;
7143a22001-08-17Honza Petrous  constant name = "enterprises.roxenis.app.roxen.global.vs"; constant tree = RISMIB_BASE_WEBSERVER_GLOBAL_VS - (MIBTREE_BASE+".");
12e6ea2001-07-19Honza Petrous  void create(object agent) { submibtab = ([
14cf2b2001-07-18Honza Petrous  // enterprises
12e6ea2001-07-19Honza Petrous  // hack2 :)
7143a22001-08-17Honza Petrous  tree+".0": agent->get_virtserv,
12e6ea2001-07-19Honza Petrous  ]); } }
14cf2b2001-07-18Honza Petrous  /* switch (attrname) { case RISMIB_BASE_WEBSERVER+".1.0": // HACK! For testing purpose only! // Server restart = 1; server shutdown = 2 if(chk_access("rw", pdata[msgid])) { setflg = 1; rdata[attrname] += ({ "int", attrval }); rdata["1.3.6.1.2.1.1.3.0"] += ({"tick", get_uptime() }); if(attrval == 1 || attrval == 2) { report_warning("SNMPagent: Initiated " + ((attrval==1)?"restart":"shutdown") + " from snmp://" + pdata[msgid]->community + "@" + pdata[msgid]->ip + "/\n"); if (attrval == 1) roxen->restart(0.5); if (attrval == 2) roxen->shutdown(0.5); } } else snmpbadcommuses++; break; case MIBTREE_BASE+".2.1.11.30.0": // The standard-based (RFC1213) method of disabling auth. traps if(chk_access("rw", pdata[msgid])) { setflg = 1; rdata[attrname] += ({ "int", attrval }); rdata["1.3.6.1.2.1.1.3.0"] += ({"tick", get_uptime() }); if(attrval == 0 || attrval == 1) { report_warning("SNMPagent: Requested " + attrval?"en":"dis" + "abling of auth. traps from snmp://" + pdata[msgid]->community + "@" + pdata[msgid]->ip + "/\n"); // here will be ena/disabling of such traps } } else snmpbadcommuses++; break; */
7e89ce2001-08-15Honza Petrous //! roxenis enterprise subtree manager //! Manages the enterprise.roxenis.* submib tree.
7143a22001-08-17Honza Petrous class SubMIBRoxenVSName {
7e89ce2001-08-15Honza Petrous  inherit SubMIBManager;
7143a22001-08-17Honza Petrous  constant name = "enterprises.roxenis.app.roxen.vs"; constant tree = RISMIB_BASE_WEBSERVER_VS - (MIBTREE_BASE+".");
7e89ce2001-08-15Honza Petrous  object agent; void create(object agentp) { agent = agentp;
7143a22001-08-17Honza Petrous  submibtab = ([ ]);
7e89ce2001-08-15Honza Petrous  } array get(string oid, mapping|void pkt) { string soid, vname;
7143a22001-08-17Honza Petrous  int vdata; array rval, arroid;
7e89ce2001-08-15Honza Petrous  SNMPAGENT_MSG(sprintf("GET(%s): %O", name, oid)); soid = oid_strip(oid);
7143a22001-08-17Honza Petrous  /* fist, we will try to find an "ordinary" object in the MIB if (functionp(rval = submibtab[soid])) { SNMPAGENT_MSG("found ordinary MIB object."); return rval(); }*/ // no, so we will try to find "tabular" object instead if(sizeof((soid = soid - (tree + "."))/".") != 2) return ({}); // exactly one point, please switch ((soid/".")[0]) { case "1": // VS_NAME vname = agent->get_virtservname(((int)(soid/".")[1])+1); if(!stringp(vname)) return ({}); // wrong index return (OBJ_STR(vname)); case "2": // VS_SDATA vdata = agent->get_virtservsdata(((int)(soid/".")[1])+1); if(vdata < 0) return ({}); // wrong index return (OBJ_COUNT(vdata)); case "3": // VS_SHDRS vdata = agent->get_virtservshdrs(((int)(soid/".")[1])+1); if(vdata < 0) return ({}); // wrong index return (OBJ_COUNT(vdata)); case "4": // VS_RDATA vdata = agent->get_virtservrdata(((int)(soid/".")[1])+1); if(vdata < 0) return ({}); // wrong index return (OBJ_COUNT(vdata)); case "5": // VS_REQS vdata = agent->get_virtservreqs(((int)(soid/".")[1])+1); if(vdata < 0) return ({}); // wrong index return (OBJ_COUNT(vdata)); } return ({});
7e89ce2001-08-15Honza Petrous  } array getnext(string oid, mapping|void pkt) {
7143a22001-08-17Honza Petrous  string soid, noid, vname; int idx, vdata; array rval, arr;
7e89ce2001-08-15Honza Petrous  SNMPAGENT_MSG(sprintf("GETNEXT(%s): %O", name, oid)); soid = oid_strip(oid); if(oid == (MIBTREE_BASE+"."+tree)) {
7143a22001-08-17Honza Petrous  soid = "1.-1"; // special case oid += ".1.-1"; // trash only } arr = ((soid = soid - (tree + "."))/"."); if(sizeof(arr) == 1) { soid = arr[0]+".-1"; // special case oid += "."+soid; // trash only } idx = (int)((soid/".")[1])+1; noid = (reverse(reverse(oid/".")[1..])*".")+"."+(string)idx; switch ((soid/".")[0]) { case "1": // VS_NAME vname = agent->get_virtservname(idx+1); if(!stringp(vname)) return ({}); // wrong index return (({noid, @OBJ_STR(vname)})); case "2": // VS_SDATA vdata = agent->get_virtservsdata(idx+1); if(vdata < 0) return ({}); // wrong index return (({noid, @OBJ_COUNT(vdata)})); case "3": // VS_SHDRS vdata = agent->get_virtservshdrs(idx+1); if(vdata < 0) return ({}); // wrong index return (({noid, @OBJ_COUNT(vdata)})); case "4": // VS_RDATA vdata = agent->get_virtservrdata(idx+1); if(vdata < 0) return ({}); // wrong index return (({noid, @OBJ_COUNT(vdata)})); case "5": // VS_REQS vdata = agent->get_virtservreqs(idx+1); if(vdata < 0) return ({}); // wrong index return (({noid, @OBJ_COUNT(vdata)})); } return ({});
7e89ce2001-08-15Honza Petrous  } }
813b312001-06-25Honza Petrous SNMPagent snmpagent; //! Global SNMPagent object