summaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2006-01-27 21:36:35 +0000
committerStef Walter <stef@memberwebs.com>2006-01-27 21:36:35 +0000
commitcadd830e5aca1f208541ea6d38da5b4a863db5cc (patch)
tree597b1bd012ddd2fb1950b4bdc84c17b69ed37e2c /daemon
parent36f86d822d09ec0d91839ee68178d8602e1970e2 (diff)
Added textual MIB parsing support. See #45
Diffstat (limited to 'daemon')
-rw-r--r--daemon/Makefile.am3
-rw-r--r--daemon/config.c10
-rw-r--r--daemon/rrdbotd.c67
-rw-r--r--daemon/rrdbotd.h19
-rw-r--r--daemon/snmp-help.c99
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;
}