Roxen.git / server / base_server / snmpagent.pike

version» Context lines:

Roxen.git/server/base_server/snmpagent.pike:1:   /* -  * $Id: snmpagent.pike,v 1.8 2001/08/14 23:24:35 hop Exp $ +  * $Id: snmpagent.pike,v 1.9 2001/08/17 00:01:11 hop Exp $    *    * The Roxen SNMP agent    * Copyright © 2001, Roxen IS.    *    * Author: Honza Petrous    * January 2001         RFC 1213 base MIB    system.* (all done)
Roxen.git/server/base_server/snmpagent.pike:24:       Known issues:    - every reload spawne a new thread, I guess that old ones are never    used then. [threads leak] // FIXME: solved by switching to the async i/o    - the OID must be minimally 5 elements long, otherwise GETNEXT return    "no such name" error    - 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 ?    - cold_start trap code isn't completed +  - tabular walking throught roxenis.app.roxen.* doesn't working    Todos:    v1.0 todo:    - cold/warm start trap generation -  +  - restart/stop    - 'basic' Roxen working variables       v1.1 todo:    - trap handling -  +  - module reloading       v2.0 todo:    - Roxen.module API for registering MIB subtree       v3.0 todo:    - SNMP v3    - security          */
Roxen.git/server/base_server/snmpagent.pike:77:   #define SNMP_OP_GETRESPONSE 2   #define SNMP_OP_SETREQUEST 3   #define SNMP_OP_TRAP 4      #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})    - #define RISMIB_BASE "1.3.6.1.4.1.8614" - #define RISMIB_BASE_WEBSERVER RISMIB_BASE+".1.1" -  +    //! The starting part of OID of every object will have, so we stripp it out   //! before making index from OID to the MIB DB - #define MIBTREE_BASE "1.3.6.1" + #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" +    #define LOG_EVENT(txt, pkt) log_event(txt, pkt)      class SNMPagent {    private int enabled;       // Global variables    private object fd; // opened UDP port    private int inited; // flag    private int snmpinpkts;    private int snmpoutpkts;
Roxen.git/server/base_server/snmpagent.pike:109:    private mixed co;    private object th;    private static object mib;    private mapping vsdb;       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); }; -  array get_snmpenaauth() { return OBJ_COUNT(snmpenaauth); }; +  array get_snmpenaauth() { return OBJ_INT(snmpenaauth); };       array get_virtserv() { return OBJ_COUNT(sizeof(vsdb)); };          void create() {    vsdb = ([]);    //disable();    }       //! Enable SNMPagent processing.    int enable() {       if(enabled)    return(enabled);    mib = SubMIBSystem(); // system.* table    if(objectp(mib)) {    // snmp.* -  mib->register(MIBTREE_BASE+"."+"2.1.11", SubMIBSnmp(this_object())); +  mib->register(SubMIBSnmp(this_object()));    // enterprises.roxenis.* -  mib->register(MIBTREE_BASE+"."+"4.1.8614", SubMIBRoxenIS(this_object())); -  mib->register(MIBTREE_BASE+"."+"4.1.8614.1.1.999.2.1.1", SubMIBRoxenVs(this_object())); +  mib->register(SubMIBRoxenVS(this_object())); +  mib->register(SubMIBRoxenVSName(this_object()));    }    if (!status())    start();    enabled = 1;    return (enabled);    }       //! Disable SNMPagent processing.    int disable() {   
Roxen.git/server/base_server/snmpagent.pike:380:    //! Adds virtual server to the DB of managed objects    int add_virtserv(int vsid) {       if(zero_type(vsdb[vsid])) {    report_debug(sprintf("SNMPagent: added server %O(#%d)\n",    roxen->configurations[vsid]->name, vsid));   //report_debug(sprintf("snmpagent:DEB: %O\n",mkmapping(indices(roxen->configurations[vsid]), values(roxen->configurations[vsid]))));    vsdb += ([vsid: roxen->configurations[vsid]]);    }    +  // some tabulars handlers ... +  +     return(1);    }       //! 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);    }    -  +  //! 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); +  } +  +     //! Deletes virtual server's specific objects from DB    int del_virtserv(int vsid) {       if(!zero_type(vsdb[vsid])) {    report_debug(sprintf("SNMPagent: deleted server %O(#%d)\n",    roxen->configurations[vsid]->name, vsid));    vsdb -= ([ vsid: 0 ]);    }       return(1);
Roxen.git/server/base_server/snmpagent.pike:445:    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. -  int register(string oid, object manager) { +  int register(object manager) {    -  if(!(oid = oid_strip(oid))) return -1; // false => bad OID +  string oid = manager->tree; +     if(oid_check(oid)) -  return 0; // false => the OID is already registered. What about stackable organization ? +  return 0; // false => the OID is already registered. +  // What about stackable organization ?    if(subtreeman[oid])    return 0; // false => already registered    subtreeman += ([oid: manager]); // FIXME: autohiding of subtree. Is it goood? -  +  SNMPAGENT_MSG(sprintf("manager %O registered for tree %O", manager->name, manager->tree));    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
Roxen.git/server/base_server/snmpagent.pike:479:       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/"."; -  for(int cnt = sizeof(s)-1; cnt>0; cnt--) +  for(int cnt = sizeof(s)-1; cnt>0; cnt--) { +  SNMPAGENT_MSG(sprintf("finding manager for tree %O", s[..cnt]*"."));    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);    }    }    -  +  SNMPAGENT_MSG("Not found any suitable manager"); +  return 0; +  } +     //! 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)))
Roxen.git/server/base_server/snmpagent.pike:528:    SNMPAGENT_MSG(sprintf("subtree match: %O", idxnums[idx]));    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--) { +  SNMPAGENT_MSG(sprintf("finding manager for tree %O", s[..cnt]*"."));    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);    }    }       }    -  +  SNMPAGENT_MSG("Not found any suitable manager");    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
Roxen.git/server/base_server/snmpagent.pike:566:       //! 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() { -  return OBJ_STR("Roxen Webserver SNMP agent v"+("$Revision: 1.8 $"/" ")[1]+" (devel. rel.)"); +  return OBJ_STR("Roxen Webserver SNMP agent v"+("$Revision: 1.9 $"/" ")[1]+" (devel. rel.)");   }      //! 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);
Roxen.git/server/base_server/snmpagent.pike:714:    // snmp.snmpEnableAuthenTraps    "2.1.11.30.0": agent->get_snmpenaauth,       ]);       }   }      //! roxenis enterprise subtree manager   //! Manages the enterprise.roxenis.* submib tree. - class SubMIBRoxenIS { + class SubMIBRoxenVS {       inherit SubMIBManager;    -  constant name = "enterprises.roxenis"; -  constant tree = "4.1.8614"; +  constant name = "enterprises.roxenis.app.roxen.global.vs"; +  constant tree = RISMIB_BASE_WEBSERVER_GLOBAL_VS - (MIBTREE_BASE+".");       void create(object agent) {       submibtab = ([    // enterprises    // hack2 :) -  "4.1.8614.1.1.999.2.1.0": agent->get_virtserv, +  tree+".0": agent->get_virtserv,    ]);    }   }      /*    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])) {
Roxen.git/server/base_server/snmpagent.pike:765:    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;   */      //! roxenis enterprise subtree manager   //! Manages the enterprise.roxenis.* submib tree. - class SubMIBRoxenVs { + class SubMIBRoxenVSName {       inherit SubMIBManager;    -  constant name = "roxenis.app.roxen.test.vs"; -  constant tree = "4.1.8614.1.1.999.2.1.1"; +  constant name = "enterprises.roxenis.app.roxen.vs"; +  constant tree = RISMIB_BASE_WEBSERVER_VS - (MIBTREE_BASE+".");       object agent;       void create(object agentp) { -  -  submibtab = ([ ]); +     agent = agentp; -  +  submibtab = ([ ]);    }       array get(string oid, mapping|void pkt) {    -  function rval; +     string soid, vname; -  +  int vdata; +  array rval, arroid;       SNMPAGENT_MSG(sprintf("GET(%s): %O", name, oid));    soid = oid_strip(oid);    -  if(sizeof((soid = soid - (tree + "."))/".") > 1) -  return ({}); // no more points, please +  /* 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(); +  }*/    -  vname = agent->get_virtservname(((int)soid)+1); +  // 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 ({});    -  +  } +     array getnext(string oid, mapping|void pkt) {    -  function rval; -  string soid, vname; -  int idx; +  string soid, noid, vname; +  int idx, vdata; +  array rval, arr;       SNMPAGENT_MSG(sprintf("GETNEXT(%s): %O", name, oid));    soid = oid_strip(oid);       if(oid == (MIBTREE_BASE+"."+tree)) { -  soid = "-1"; // special case -  oid += ".-1"; // trash only -  } else if(sizeof((soid = soid - (tree + "."))/".") > 1) -  return ({}); // no more points, please +  soid = "1.-1"; // special case +  oid += ".1.-1"; // trash only +  }    -  idx = (int)soid+1; +  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 -  soid = (reverse(reverse(oid/".")[1..])*".")+"."+(string)idx; -  return (({soid, @OBJ_STR(vname)})); +  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 ({}); +  }      }      SNMPagent snmpagent;   //! Global SNMPagent object