diff options
Diffstat (limited to 'daemon')
| -rw-r--r-- | daemon/Makefile.am | 3 | ||||
| -rw-r--r-- | daemon/config.c | 10 | ||||
| -rw-r--r-- | daemon/rrdbotd.c | 67 | ||||
| -rw-r--r-- | daemon/rrdbotd.h | 19 | ||||
| -rw-r--r-- | daemon/snmp-help.c | 99 | 
5 files changed, 160 insertions, 38 deletions
| diff --git a/daemon/Makefile.am b/daemon/Makefile.am index c83aabe..969bafb 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -6,6 +6,7 @@ rrdbotd_SOURCES = rrdbotd.c rrdbotd.h config.c usuals.h \                  ../common/server-mainloop.c ../common/server-mainloop.h \                  ../common/sock-any.h ../common/sock-any.c \                  ../common/stringx.h ../common/stringx.c \ -                ../common/hash.h ../common/hash.c +                ../common/hash.h ../common/hash.c \ +                ../mib/parse.c  rrdbotd_CFLAGS = -I${top_srcdir}/common/ -I${top_srcdir}/bsnmp/ -I${top_srcdir}  rrdbotd_LDADD = $(top_builddir)/bsnmp/libbsnmp-custom.a diff --git a/daemon/config.c b/daemon/config.c index 78ad04b..d33ab69 100644 --- a/daemon/config.c +++ b/daemon/config.c @@ -233,6 +233,9 @@ parse_uri(char *uri, char** scheme, char** host,      *path = uri; +    while((*path)[0] == '/') +        (*path)++; +      /* This copy only for error messages */      free(copy);  } @@ -303,8 +306,11 @@ parse_item(const char* field, char* uri, config_ctx *ctx)      ritem->value = RB_UNKNOWN;      /* And parse the OID */ -    if(rb_parse_mib(path, &(ritem->snmpfield)) == -1) -        errx(2, "%s: invalid OID: %s", ctx->confname, path + 1); +    if(rb_snmp_parse_mib(path, &(ritem->snmpfield)) == -1) +        errx(2, "%s: invalid MIB: %s", ctx->confname, path); + +    rb_messagex(LOG_DEBUG, "parsed MIB into oid: %s -> %s", path, +                asn_oid2str(&(ritem->snmpfield.var)));      /* And add it to the list */      ritem->next = ctx->items; diff --git a/daemon/rrdbotd.c b/daemon/rrdbotd.c index 39094cd..8434e35 100644 --- a/daemon/rrdbotd.c +++ b/daemon/rrdbotd.c @@ -62,10 +62,41 @@  /* The one main state object */  rb_state g_state; +/* Whether we print warnings when loading MIBs or not */ +int g_mib_warnings = 0; +  /* Some logging flags */  static int daemonized = 0;  static int debug_level = LOG_ERR; +#include "mib/parse.h" + +static void +test(int argc, char* argv[]) +{ +    struct snmp_value val; +    mib_node n, n2; + +    debug_level = 4; + +    if(argc < 2) +        errx(2, "specify arguments"); + +    while(argc > 1) +    { +        if(rb_snmp_parse_mib(argv[1], &val) == -1) +            warnx("couldn't parse mib value: %s", argv[1]); +        else +            fprintf(stderr, "the oid is: %s\n", asn_oid2str(&(val.var))); + +        argc--; +        argv++; +    } + +    rb_mib_uninit(); +    exit(1); +} +  /* -----------------------------------------------------------------------------   * CLEANUP   */ @@ -120,8 +151,8 @@ rb_atexit(voidfunc func, void* data)   * LOGGING   */ -static void -vmessage (int level, int err, const char* msg, va_list ap) +void +rb_vmessage(int level, int err, const char* msg, va_list ap)  {      #define MAX_MSGLEN  1024      char buf[MAX_MSGLEN]; @@ -156,7 +187,7 @@ rb_messagex (int level, const char* msg, ...)  {      va_list ap;      va_start(ap, msg); -    vmessage(level, 0, msg, ap); +    rb_vmessage(level, 0, msg, ap);      va_end(ap);  } @@ -165,7 +196,7 @@ rb_message (int level, const char* msg, ...)  {      va_list ap;      va_start(ap, msg); -    vmessage(level, 1, msg, ap); +    rb_vmessage(level, 1, msg, ap);      va_end(ap);  } @@ -176,7 +207,7 @@ rb_message (int level, const char* msg, ...)  static void  usage()  { -    fprintf(stderr, "usage: rrdbotd [-c confdir] [-w workdir] [-d level] [-p pidfile] [-r retries] [-t timeout]\n"); +    fprintf(stderr, "usage: rrdbotd [-M] [-c confdir] [-w workdir] [-d level] [-p pidfile] [-r retries] [-t timeout]\n");      fprintf(stderr, "       rrdbotd -v\n");      exit(2);  } @@ -212,6 +243,8 @@ main(int argc, char* argv[])      char ch;      char* t; +    /* test(argc, argv); */ +      /* Initialize the state stuff */      memset(&g_state, 0, sizeof(g_state)); @@ -221,7 +254,7 @@ main(int argc, char* argv[])      g_state.timeout = DEFAULT_TIMEOUT;      /* Parse the arguments nicely */ -    while((ch = getopt(argc, argv, "c:d:p:r:t:w:v")) != -1) +    while((ch = getopt(argc, argv, "c:d:Mp:r:t:w:v")) != -1)      {          switch(ch)          { @@ -240,6 +273,11 @@ main(int argc, char* argv[])              debug_level += LOG_ERR;              break; +        /* MIB load warnings */ +        case 'M': +            g_mib_warnings = 1; +            break; +          /* Write out a pid file */          case 'p':              pidfile = optarg; @@ -289,6 +327,11 @@ main(int argc, char* argv[])      /* Parse config and setup SNMP system */      rb_config_parse(); + +    /* As an optimization we unload the MIB processing data here */ +    rb_mib_uninit(); + +    /* Rev up the main engine */      rb_snmp_engine_init();      if(daemonize) @@ -302,12 +345,12 @@ main(int argc, char* argv[])      }      /* Handle signals */ -     signal(SIGPIPE, SIG_IGN); -     signal(SIGHUP, SIG_IGN); -     signal(SIGINT,  on_quit); -     signal(SIGTERM, on_quit); -     siginterrupt(SIGINT, 1); -     siginterrupt(SIGTERM, 1); +    signal(SIGPIPE, SIG_IGN); +    signal(SIGHUP, SIG_IGN); +    signal(SIGINT,  on_quit); +    signal(SIGTERM, on_quit); +    siginterrupt(SIGINT, 1); +    siginterrupt(SIGTERM, 1);      /* Open the system log */      openlog("rrdbotd", 0, LOG_DAEMON); diff --git a/daemon/rrdbotd.h b/daemon/rrdbotd.h index 74f8fd5..ce16ebd 100644 --- a/daemon/rrdbotd.h +++ b/daemon/rrdbotd.h @@ -41,6 +41,7 @@  #include <values.h>  #include <stdint.h> +#include <stdarg.h>  #include "asn1.h"  #include "snmp.h" @@ -147,8 +148,9 @@ extern rb_state g_state;   * UTILITIES (rrdbotd.c)   */ -void rb_messagex (int level, const char* msg, ...); -void rb_message (int level, const char* msg, ...); +void rb_messagex(int level, const char* msg, ...); +void rb_message(int level, const char* msg, ...); +void rb_vmessage(int level, int err, const char* msg, va_list ap);  typedef void (*voidfunc)(void*);  void rb_atexit (voidfunc func, void* data); @@ -179,4 +181,17 @@ void rb_snmp_engine_uninit();  void rb_rrd_update(rb_poller *poll); +/* ----------------------------------------------------------------------------- + * MIB PARSING + */ + +typedef void* mib_node; + +void rb_mib_init(int warnings); +mib_node rb_mib_lookup(const char* match); +int rb_mib_subid(mib_node n, const char* name); +void rb_mib_oid(mib_node n, struct asn_oid* oid); +mib_node rb_mib_node(struct asn_oid* oid); +void rb_mib_uninit(); +  #endif /* __RRDBOTD_H__ */ diff --git a/daemon/snmp-help.c b/daemon/snmp-help.c index cf13d40..8a54bb1 100644 --- a/daemon/snmp-help.c +++ b/daemon/snmp-help.c @@ -46,9 +46,13 @@  #include "stringx.h"  #include "rrdbotd.h" +/* Whether we print warnings when loading MIBs or not */ +extern int g_mib_warnings; +  static int -parse_numeric_mib(const char* mib, struct asn_oid* oid) +parse_mixed_mib(const char* mib, struct asn_oid* oid)  { +    mib_node n;      int ret = 0;      unsigned int sub;      char* next; @@ -58,37 +62,67 @@ parse_numeric_mib(const char* mib, struct asn_oid* oid)      memset(oid, 0, sizeof(*oid)); -    copy = src = strdup(mib); -    if(!src) +    copy = strdup(mib); +    if(!copy) +    { +        errno = ENOMEM;          return -1; +    } -    while(src && *src) +    for(src = copy; src && *src; src = next)      {          next = strchr(src, '.');          if(next) +        {              *next = 0; +            next++; +        }          sub = strtoul(src, &t, 10); -        /* Too many parts */ -        if(oid->len > ASN_MAXOIDLEN) -            ret = -1; +        /* An invalid number, try getting a named MIB */ +        if(*t || sub < 0) +        { +            /* Only initializes first time around */ +            rb_mib_init(g_mib_warnings); + +            /* +             * If we haven't parsed anything yet, try a symbolic +             * search for root +             */ + +            if(oid->len == 0) +            { +                n = rb_mib_lookup(src); +                if(n) +                { +                    /* That took care of it */ +                    rb_mib_oid(n, oid); +                    continue; +                } +            } + +            /* Try a by name search for sub item */ +            n = rb_mib_node(oid); +            if(n == NULL) +                sub = -1; +            else +                sub = rb_mib_subid(n, src); +        } -        /* An invalid number */ -        if(*t) +        /* Make sure this is a valid part */ +        if(sub < 0 || (oid->len == 0 && sub < 1) || sub >= ASN_MAXID)              ret = -1; -        /* Make sure this is a valid part */ -        if((oid->len == 0 && sub < 1) || sub < 0 || sub >= ASN_MAXID) -            ret -1; +        /* Too many parts */ +        if(oid->len > ASN_MAXOIDLEN) +            ret = -1;          if(ret < 0)              break;          oid->subs[oid->len] = sub;          oid->len++; - -        src = next ? next + 1 : NULL;      }      free(copy); @@ -96,16 +130,39 @@ parse_numeric_mib(const char* mib, struct asn_oid* oid)  }  int -rb_parse_mib(const char* mib, struct snmp_value* value) +rb_snmp_parse_mib(const char* mib, struct snmp_value* value)  { -    /* -     * TODO: Eventually we'll have code here to parse symbolic -     * names, and initialize snmp_value to the right type and -     * all that jazz. For now we just have numeric OID support. -     */ +    int ret; +    mib_node n;      value->syntax = SNMP_SYNTAX_NULL;      memset(&(value->v), 0, sizeof(value->v)); -    return parse_numeric_mib(mib, &(value->var)); +    /* An initial dot */ +    if(*mib == '.') +        mib++; + +    /* +     * First try parsing a numeric OID. This will fall +     * back to mixed mode MIB's if necassary. Allows us +     * to avoid loading all the MIB files when not +     * necessary +     */ + +    ret = parse_mixed_mib(mib, &(value->var)); + +    /* Next try a symolic search */ +    if(ret == -1) +    { +        rb_mib_init(g_mib_warnings); + +        n = rb_mib_lookup(mib); +        if(n == NULL) +            return -1; + +        rb_mib_oid(n, &(value->var)); +        return 0; +    } + +    return ret;  } | 
