summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2006-04-04 21:07:18 +0000
committerStef Walter <stef@memberwebs.com>2006-04-04 21:07:18 +0000
commit1e735c038c86294df2ecfbd6a39abcfab4b3e8c3 (patch)
tree55dc3d3288d17d53fadf3471bb465fefb1b42b12
parent1fe43cb40fb54412528b7538718a457d2167c603 (diff)
Move functionality for parsing MIBs, SNMP into common files.
-rw-r--r--bsnmp/snmp.c43
-rw-r--r--bsnmp/snmp.h2
-rw-r--r--common/config-parser.c42
-rw-r--r--common/config-parser.h3
-rw-r--r--daemon/Makefile.am4
-rw-r--r--daemon/config.c65
-rw-r--r--daemon/rrdbotd.c12
-rw-r--r--daemon/rrdbotd.h19
-rw-r--r--daemon/snmp-engine.c53
-rw-r--r--mib/mib-parser.c381
-rw-r--r--mib/mib-parser.h63
-rw-r--r--mib/parse-net-snmp.patch27
-rw-r--r--mib/parse.c8
13 files changed, 571 insertions, 151 deletions
diff --git a/bsnmp/snmp.c b/bsnmp/snmp.c
index f758262..6b2cc01 100644
--- a/bsnmp/snmp.c
+++ b/bsnmp/snmp.c
@@ -1079,3 +1079,46 @@ snmp_printf_func(const char *fmt, ...)
vfprintf(stderr, fmt, ap);
va_end(ap);
}
+
+/* -----------------------------------------------------------------------------
+ * ERR MESSAGE HANDLING
+ */
+
+/* All SNMP error messages */
+static struct
+{
+ int code;
+ const char* msg;
+} snmp_errmsgs[] = {
+ { SNMP_ERR_NOERROR, "Success" },
+ { SNMP_ERR_TOOBIG, "SNMP packet or response too big" },
+ { SNMP_ERR_NOSUCHNAME, "Unknown variable name" },
+ { SNMP_ERR_BADVALUE, "Incorrect syntax or value when modifing a variable" },
+ { SNMP_ERR_READONLY, "Value is readonly" },
+ { SNMP_ERR_GENERR, "Unspecified general error" },
+ { SNMP_ERR_NO_ACCESS, "Access was denied to the object" },
+ { SNMP_ERR_WRONG_TYPE, "The object type is incorrect for the object" },
+ { SNMP_ERR_WRONG_LENGTH, "Incorrect specified for the object." },
+ { SNMP_ERR_WRONG_ENCODING, "Incorrect encoding specified for the object." },
+ { SNMP_ERR_WRONG_VALUE, "Not possible to set this value for the object." },
+ { SNMP_ERR_NO_CREATION, "The value cannot be created." },
+ { SNMP_ERR_INCONS_VALUE, "Not possible to set the value at this time." },
+ { SNMP_ERR_RES_UNAVAIL, "The resource is not availeble" },
+ { SNMP_ERR_COMMIT_FAILED, "Commit failed" },
+ { SNMP_ERR_UNDO_FAILED, "Undo failed" },
+ { SNMP_ERR_AUTH_ERR, "A problem occured during authentication" },
+ { SNMP_ERR_NOT_WRITEABLE, "The variable cannot be written or created." },
+ { SNMP_ERR_INCONS_NAME, "The variable does not exist." }
+};
+
+const char*
+snmp_get_errmsg (int code)
+{
+ int i;
+ for(i = 0; i < sizeof(snmp_errmsgs) / sizeof(snmp_errmsgs[0]); i++)
+ {
+ if(code == snmp_errmsgs[i].code)
+ return snmp_errmsgs[i].msg;
+ }
+ return NULL;
+}
diff --git a/bsnmp/snmp.h b/bsnmp/snmp.h
index 1ae0775..ea04ffa 100644
--- a/bsnmp/snmp.h
+++ b/bsnmp/snmp.h
@@ -171,4 +171,6 @@ extern void (*snmp_printf)(const char *, ...);
#define TRUTH_GET(T) (((T) == 1) ? 1 : 0)
#define TRUTH_OK(T) ((T) == 1 || (T) == 2)
+const char* snmp_get_errmsg (int code);
+
#endif
diff --git a/common/config-parser.c b/common/config-parser.c
index 905e019..c54b91e 100644
--- a/common/config-parser.c
+++ b/common/config-parser.c
@@ -314,3 +314,45 @@ cfg_parse_dir(const char* dirname, void* data)
return ret;
}
+
+const char*
+cfg_parse_uri (char *uri, char** scheme, char** host, char** user, char** path)
+{
+ char* t;
+
+ *scheme = NULL;
+ *host = NULL;
+ *user = NULL;
+ *path = NULL;
+
+ *scheme = strsep(&uri, ":");
+ if(uri == NULL || (uri[0] != '/' && uri[1] != '/'))
+ return "invalid uri";
+
+ uri += 2;
+ *host = strsep(&uri, "/");
+ if(*host[0])
+ {
+ /* Parse the community out from the host */
+ t = strchr(*host, '@');
+ if(t)
+ {
+ *t = 0;
+ *user = *host;
+ *host = t + 1;
+ }
+ }
+
+ if(!*host[0])
+ return "invalid uri: no host name found";
+
+ if(!uri || !uri[0] || !uri[1])
+ return "invalid uri: no path found";
+
+ *path = uri;
+
+ while((*path)[0] == '/')
+ (*path)++;
+
+ return NULL;
+}
diff --git a/common/config-parser.h b/common/config-parser.h
index 174bac2..11949a2 100644
--- a/common/config-parser.h
+++ b/common/config-parser.h
@@ -47,4 +47,7 @@ extern int cfg_error(const char* filename, const char* errmsg, void* data);
int cfg_parse_dir(const char* dirname, void* data);
int cfg_parse_file(const char* filename, void* data, char** memory);
+/* A helper for parsing URIs */
+const char* cfg_parse_uri (char *uri, char** scheme, char** host, char** user, char** path);
+
#endif /* __CONFIG_PARSER_H__ */
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 466353b..63f5169 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -2,13 +2,13 @@
sbin_PROGRAMS = rrdbotd
rrdbotd_SOURCES = rrdbotd.c rrdbotd.h config.c \
- snmp-help.c snmp-engine.c rrd-update.c \
+ snmp-engine.c rrd-update.c \
../common/server-mainloop.c ../common/server-mainloop.h \
../common/sock-any.h ../common/sock-any.c \
../common/compat.h ../common/compat.c \
../common/hash.h ../common/hash.c \
../common/config-parser.h ../common/config-parser.c \
- ../mib/parse.c
+ ../mib/mib-parser.h ../mib/mib-parser.c
rrdbotd_CFLAGS = -I${top_srcdir}/common/ -I${top_srcdir}/bsnmp/ -I${top_srcdir} \
-DCONF_PREFIX=\"$(sysconfdir)\" -DDATA_PREFIX=\"$(datadir)\"
rrdbotd_LDADD = $(top_builddir)/bsnmp/libbsnmp-custom.a
diff --git a/daemon/config.c b/daemon/config.c
index 9a5320b..d95de8a 100644
--- a/daemon/config.c
+++ b/daemon/config.c
@@ -44,6 +44,8 @@
#include <string.h>
#include <err.h>
+#include <mib/mib-parser.h>
+
#include "rrdbotd.h"
#include "config-parser.h"
@@ -189,68 +191,27 @@ config_done(config_ctx* ctx)
ctx->timeout = 0;
}
-static void
-parse_uri(char *uri, char** scheme, char** host,
- char** user, char** path, config_ctx* ctx)
-{
- /* Copy only for error messages as we mess with original */
- char* copy = strdup(uri);
- char* t;
-
- *host = NULL;
- *path = NULL;
- *user = NULL;
-
- *scheme = strsep(&uri, ":");
- if(uri == NULL)
- errx(2, "%s: invalid poll uri (scheme invalid): %s", ctx->confname, copy);
-
- if((uri[0] != '/' && uri[1] != '/'))
- errx(2, "%s: invalid poll uri (scheme invalid): %s", ctx->confname, copy);
-
- uri += 2;
- *host = strsep(&uri, "/");
- if(*host[0])
- {
- /* Parse the user name out from the host */
- t = strchr(*host, '@');
- if(t)
- {
- *t = 0;
- *user = *host;
- *host = t + 1;
- }
- }
-
- if(!*host[0])
- errx(2, "%s: invalid poll uri (no hostname found): %s", ctx->confname, copy);
-
- if(!uri || !uri[0] || !uri[1])
- errx(2, "%s: invalid poll uri (no pathname found): %s", ctx->confname, copy);
-
- *path = uri;
-
- while((*path)[0] == '/')
- (*path)++;
-
- /* This copy only for error messages */
- free(copy);
-}
-
static rb_item*
parse_item(const char* field, char* uri, config_ctx *ctx)
{
rb_item *ritem;
rb_host *rhost;
+ const char *msg;
+ char* copy;
+ char* scheme;
char* host;
char* user;
- char* scheme;
char* path;
/* Parse the SNMP URI */
- parse_uri(uri, &scheme, &host, &user, &path, ctx);
- ASSERT(scheme && host && path);
+ copy = strdup(uri);
+ msg = cfg_parse_uri(uri, &scheme, &host, &user, &path);
+ if(msg)
+ errx(2, "%s: %s: %s", ctx->confname, msg, copy);
+ free(copy);
+
+ ASSERT(host && path);
/* TODO: SNMP version support */
@@ -299,7 +260,7 @@ parse_item(const char* field, char* uri, config_ctx *ctx)
ritem->vtype = VALUE_UNSET;
/* And parse the OID */
- if(rb_snmp_parse_mib(path, &(ritem->snmpfield)) == -1)
+ if(mib_parse(path, &(ritem->snmpfield)) == -1)
errx(2, "%s: invalid MIB: %s", ctx->confname, path);
rb_messagex(LOG_DEBUG, "parsed MIB into oid: %s -> %s", path,
diff --git a/daemon/rrdbotd.c b/daemon/rrdbotd.c
index 261955d..e2b0248 100644
--- a/daemon/rrdbotd.c
+++ b/daemon/rrdbotd.c
@@ -46,6 +46,7 @@
#include <bsnmp/asn1.h>
#include <bsnmp/snmp.h>
+#include <mib/mib-parser.h>
#include "rrdbotd.h"
#include "server-mainloop.h"
@@ -53,7 +54,6 @@
/* The default command line options */
#define DEFAULT_CONFIG CONF_PREFIX "/rrdbot"
#define DEFAULT_WORK "/var/db/rrdbot"
-#define DEFAULT_MIB DATA_PREFIX "/mib"
#define DEFAULT_RETRIES 3
#define DEFAULT_TIMEOUT 5
@@ -64,10 +64,6 @@
/* The one main state object */
rb_state g_state;
-/* Whether we print warnings when loading MIBs or not */
-const char* g_mib_directory = DEFAULT_MIB;
-int g_mib_warnings = 0;
-
/* Some logging flags */
static int daemonized = 0;
static int debug_level = LOG_ERR;
@@ -251,12 +247,12 @@ main(int argc, char* argv[])
/* mib directory */
case 'm':
- g_mib_directory = optarg;
+ mib_directory = optarg;
break;
/* MIB load warnings */
case 'M':
- g_mib_warnings = 1;
+ mib_warnings = 1;
break;
/* Write out a pid file */
@@ -309,7 +305,7 @@ main(int argc, char* argv[])
rb_config_parse();
/* As an optimization we unload the MIB processing data here */
- rb_mib_uninit();
+ mib_uninit();
/* Rev up the main engine */
rb_snmp_engine_init();
diff --git a/daemon/rrdbotd.h b/daemon/rrdbotd.h
index 0b7b0e1..061beb2 100644
--- a/daemon/rrdbotd.h
+++ b/daemon/rrdbotd.h
@@ -167,12 +167,6 @@ void rb_config_parse();
void rb_config_free();
/* -----------------------------------------------------------------------------
- * SNMP HELPERS (snmp-help.c)
- */
-
-int rb_snmp_parse_mib(const char* oid, struct snmp_value* value);
-
-/* -----------------------------------------------------------------------------
* SNMP ENGINE (snmp-engine.c)
*/
@@ -185,17 +179,4 @@ void rb_snmp_engine_uninit();
void rb_rrd_update(rb_poller *poll);
-/* -----------------------------------------------------------------------------
- * MIB PARSING
- */
-
-typedef void* mib_node;
-
-void rb_mib_init(const char* dir, 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-engine.c b/daemon/snmp-engine.c
index a1f773c..e4bf9b7 100644
--- a/daemon/snmp-engine.c
+++ b/daemon/snmp-engine.c
@@ -58,37 +58,6 @@ static uint32_t snmp_request = 100000;
static unsigned char snmp_buffer[0x1000];
/* -----------------------------------------------------------------------------
- * CONSTANTS
- */
-
-/* All SNMP error messages */
-static struct
-{
- int code;
- const char* msg;
-} snmp_errmsgs[] = {
- { SNMP_ERR_NOERROR, "Success" },
- { SNMP_ERR_TOOBIG, "SNMP packet or response too big" },
- { SNMP_ERR_NOSUCHNAME, "Unknown variable name" },
- { SNMP_ERR_BADVALUE, "Incorrect syntax or value when modifing a variable" },
- { SNMP_ERR_READONLY, "Value is readonly" },
- { SNMP_ERR_GENERR, "Unspecified general error" },
- { SNMP_ERR_NO_ACCESS, "Access was denied to the object" },
- { SNMP_ERR_WRONG_TYPE, "The object type is incorrect for the object" },
- { SNMP_ERR_WRONG_LENGTH, "Incorrect specified for the object." },
- { SNMP_ERR_WRONG_ENCODING, "Incorrect encoding specified for the object." },
- { SNMP_ERR_WRONG_VALUE, "Not possible to set this value for the object." },
- { SNMP_ERR_NO_CREATION, "The value cannot be created." },
- { SNMP_ERR_INCONS_VALUE, "Not possible to set the value at this time." },
- { SNMP_ERR_RES_UNAVAIL, "The resource is not availeble" },
- { SNMP_ERR_COMMIT_FAILED, "Commit failed" },
- { SNMP_ERR_UNDO_FAILED, "Undo failed" },
- { SNMP_ERR_AUTH_ERR, "A problem occured during authentication" },
- { SNMP_ERR_NOT_WRITEABLE, "The variable cannot be written or created." },
- { SNMP_ERR_INCONS_NAME, "The variable does not exist." }
-};
-
-/* -----------------------------------------------------------------------------
* REQUESTS
*/
@@ -526,7 +495,7 @@ receive_resp(int fd, int type, void* arg)
struct asn_buf b;
rb_request* req;
const char* msg;
- int len, ret, i;
+ int len, ret;
int32_t ip;
ASSERT(snmp_socket == fd);
@@ -570,19 +539,13 @@ receive_resp(int fd, int type, void* arg)
/* Check for errors */
if(pdu.error_status != SNMP_ERR_NOERROR)
{
- msg = NULL;
- for(i = 0; i < countof(snmp_errmsgs); i++)
- {
- if(pdu.error_status == snmp_errmsgs[i].code)
- {
- rb_message(LOG_ERR, "snmp error from host '%s': %s",
- hostname, snmp_errmsgs[i].msg);
- return;
- }
- }
-
- rb_message(LOG_ERR, "unknown snmp error from host '%s': %d",
- hostname, pdu.error_status);
+ msg = snmp_get_errmsg (pdu.error_status);
+ if(msg)
+ rb_message(LOG_ERR, "snmp error from host '%s': %s",
+ hostname, msg);
+ else
+ rb_message(LOG_ERR, "unknown snmp error from host '%s': %d",
+ hostname, pdu.error_status);
return;
}
diff --git a/mib/mib-parser.c b/mib/mib-parser.c
new file mode 100644
index 0000000..f4b8c9d
--- /dev/null
+++ b/mib/mib-parser.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2005, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+/*
+ * This file is not compiled on it's own. It's included into parse.c
+ * and provides compatibility definitions for making it work without
+ * the rest of net-snmp
+ */
+
+#include "usuals.h"
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <err.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+
+#include "parse.h"
+#include "mib-parser.h"
+
+/* Whether we print warnings when loading MIBs or not */
+const char* mib_directory = DEFAULT_MIB;
+int mib_warnings = 0;
+static int initialized = 0;
+
+/* -----------------------------------------------------------------------------
+ * DEFINITIONS
+ */
+
+#define FALSE 0
+#define TRUE 1
+
+/* No need to implement these */
+#define DEBUGMSGTL(x)
+#define set_function(tp)
+
+/* Just return the tree head */
+#define get_tree_head() \
+ (tree_head)
+
+#define snmp_get_do_debugging() (0)
+
+typedef u_long oid;
+
+#define NETSNMP_DS_LIBRARY_ID 0
+#define NETSNMP_DS_LIB_MIB_WARNINGS 1
+#define NETSNMP_DS_LIB_MIB_REPLACE 2
+#define NETSNMP_DS_LIB_SAVE_MIB_DESCRS 3
+#define NETSNMP_DS_LIB_MIB_ERRORS 4
+#define NETSNMP_DS_LIB_MIB_PARSE_LABEL 5
+#define NETSNMP_DS_LIB_MIB_COMMENT_TERM 6
+
+#define netsnmp_ds_get_boolean(d, v) \
+ netsnmp_ds_get_int(d, v)
+
+static int
+netsnmp_ds_get_int(int dummy, int var)
+{
+ switch(var)
+ {
+ case NETSNMP_DS_LIB_MIB_WARNINGS:
+ return mib_warnings;
+ case NETSNMP_DS_LIB_MIB_REPLACE:
+ return 0;
+ case NETSNMP_DS_LIB_SAVE_MIB_DESCRS:
+ return 0;
+ case NETSNMP_DS_LIB_MIB_PARSE_LABEL:
+ return 1;
+ case NETSNMP_DS_LIB_MIB_COMMENT_TERM:
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+#define netsnmp_ds_set_int(a, b, c)
+#define netsnmp_ds_set_boolean(a, b, c)
+#define netsnmp_ds_toggle_boolean(a, b)
+
+static void
+snmp_log(int level, const char* msg, ...)
+{
+ va_list ap;
+
+ if(level >= LOG_WARNING && !mib_warnings)
+ return;
+
+ va_start(ap, msg);
+ vwarnx(msg, ap);
+ va_end(ap);
+}
+
+/* Only used to open files */
+static void
+snmp_log_perror(const char* file)
+{
+ warn("couldn't open file: %s", file);
+}
+
+#define SNMP_FREE(s) do { if (s) { free((void *)s); s=NULL; } } while(0)
+
+/* -----------------------------------------------------------------------------
+ * RRDBOT GLUE CODE
+ */
+
+static void
+clear_tree_flags(struct tree *tp)
+{
+ for( ; tp; tp = tp->next_peer)
+ {
+ tp->reported = 0;
+ if(tp->child_list)
+ clear_tree_flags(tp->child_list);
+ }
+}
+
+void
+mib_init()
+{
+ if(initialized)
+ return;
+
+ init_mib_internals();
+ add_mibdir(mib_directory);
+ read_all_mibs();
+
+ warnx("loaded all MIB files");
+ initialized = 1;
+}
+
+mib_node
+mib_lookup(const char* match)
+{
+ extern struct tree *tree_head;
+ struct tree* mib;
+
+ ASSERT(initialized);
+
+ clear_tree_flags(tree_head);
+ mib = find_best_tree_node(match, NULL, NULL);
+ return (mib_node)mib;
+}
+
+int
+mib_subid(mib_node n, const char* name)
+{
+ struct tree *parent = (struct tree*)n;
+ struct tree *tp = NULL;
+
+ ASSERT(initialized);
+
+ for(tp = parent->child_list; tp; tp = tp->next_peer)
+ {
+ if(strcasecmp(name, tp->label) == 0)
+ return tp->subid;
+ }
+
+ return -1;
+}
+
+void
+mib_oid(mib_node n, struct asn_oid* oid)
+{
+ struct tree* mib = (struct tree*)n;
+ struct tree *tp = NULL;
+ int len;
+
+ ASSERT(mib);
+
+ /* Figure out where to start */
+ len = 0;
+ for(tp = mib; tp; tp = tp->parent)
+ len++;
+
+ oid->len = len;
+ for(tp = mib; tp; tp = tp->parent)
+ oid->subs[--len] = tp->subid;
+}
+
+mib_node
+mib_get_node(struct asn_oid* oid)
+{
+ extern struct tree *tree_head;
+ struct tree *tp = NULL;
+ asn_subid_t subid;
+ int i;
+
+ ASSERT(initialized);
+
+ for(i = 0, tp = tree_head; tp && i < oid->len;
+ i++, tp = tp ? tp->child_list : NULL)
+ {
+ subid = oid->subs[i];
+
+ while(tp && tp->subid != subid)
+ tp = tp->next_peer;
+
+ /* Did we find a match? */
+ if(tp && i == oid->len - 1)
+ break;
+ }
+
+ return tp;
+}
+
+void
+mib_uninit()
+{
+ if(initialized) {
+ unload_all_mibs();
+ warnx("unloaded all MIB files");
+ }
+ initialized = 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * INCLUDE parse.c
+ */
+
+#include "parse.c"
+
+/* -------------------------------------------------------------------------- */
+
+static int
+parse_mixed_mib(const char* mib, struct asn_oid* oid)
+{
+ mib_node n;
+ int ret = 0;
+ unsigned int sub;
+ char* next;
+ char* t;
+ char* copy;
+ char* src;
+
+ memset(oid, 0, sizeof(*oid));
+
+ copy = strdup(mib);
+ if(!copy)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ for(src = copy; src && *src; src = next)
+ {
+ next = strchr(src, '.');
+ if(next)
+ {
+ *next = 0;
+ next++;
+ }
+
+ sub = strtoul(src, &t, 10);
+
+ /* An invalid number, try getting a named MIB */
+ if(*t || sub < 0)
+ {
+ /* Only initializes first time around */
+ mib_init();
+
+ /*
+ * If we haven't parsed anything yet, try a symbolic
+ * search for root
+ */
+
+ if(oid->len == 0)
+ {
+ n = mib_lookup(src);
+ if(n)
+ {
+ /* That took care of it */
+ mib_oid(n, oid);
+ continue;
+ }
+ }
+
+ /* Try a by name search for sub item */
+ n = mib_get_node(oid);
+ if(n == NULL)
+ sub = -1;
+ else
+ sub = mib_subid(n, src);
+ }
+
+ /* Make sure this is a valid part */
+ if(sub < 0 || (oid->len == 0 && sub < 1) || 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++;
+ }
+
+ free(copy);
+ return ret;
+}
+
+int
+mib_parse(const char* mib, struct snmp_value* value)
+{
+ int ret;
+ mib_node n;
+
+ value->syntax = SNMP_SYNTAX_NULL;
+ memset(&(value->v), 0, sizeof(value->v));
+
+ /* 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)
+ {
+ mib_init();
+
+ n = mib_lookup(mib);
+ if(n == NULL)
+ return -1;
+
+ mib_oid(n, &(value->var));
+ return 0;
+ }
+
+ return ret;
+}
diff --git a/mib/mib-parser.h b/mib/mib-parser.h
new file mode 100644
index 0000000..0c4fc61
--- /dev/null
+++ b/mib/mib-parser.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+#ifndef __MIB_PARSER_H__
+#define __MIB_PARSER_H__
+
+#include "config.h"
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+
+#define DEFAULT_MIB DATA_PREFIX "/mib"
+
+/* Whether we print warnings when loading MIBs or not */
+extern const char* mib_directory;
+extern int mib_warnings;
+
+typedef void* mib_node;
+
+void mib_init();
+mib_node mib_lookup(const char* match);
+int mib_subid(mib_node n, const char* name);
+void mib_oid(mib_node n, struct asn_oid* oid);
+mib_node mib_get_node(struct asn_oid* oid);
+void mib_uninit();
+
+int mib_parse(const char* oid, struct snmp_value* value);
+
+#endif /* __MIB_PARSER_H__ */
diff --git a/mib/parse-net-snmp.patch b/mib/parse-net-snmp.patch
index 31b0e81..04435c1 100644
--- a/mib/parse-net-snmp.patch
+++ b/mib/parse-net-snmp.patch
@@ -1,5 +1,5 @@
--- parse.c.orig 2006-01-27 14:11:27.000000000
-+++ parse.c 2006-01-27 15:20:14.000000000
++++ parse.c 2006-04-04 16:04:46.000000000
@@ -1,4 +1,11 @@
/*
+ * Nate Nielsen
@@ -12,7 +12,7 @@
* parse.c
*
* Update: 1998-09-22 <mslifcak@iss.net>
-@@ -47,75 +54,29 @@
+@@ -47,75 +54,22 @@
* Use is subject to license terms specified in the COPYING file
* distributed with the Net-SNMP package.
*/
@@ -33,7 +33,7 @@
-#else
-#include <strings.h>
-#endif
--#include <ctype.h>
+ #include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <dirent.h>
@@ -41,12 +41,7 @@
-/*
- * Wow. This is ugly. -- Wes
-+#include "parse.h"
-+
-+/*
-+ * A file with compatibility definitions for making the following
-+ * code work without the net-snmp library and all that.
- */
+- */
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
@@ -89,10 +84,7 @@
-#if HAVE_DMALLOC_H
-#include <dmalloc.h>
-#endif
-+#include "parse-compat.inc.c"
-+
-+/* -------------------------------------------------------------------------- */
-+
++#include "parse.h"
-#include <net-snmp/types.h>
-#include <net-snmp/output_api.h>
@@ -102,10 +94,11 @@
-#include <net-snmp/library/parse.h>
-#include <net-snmp/library/mib.h>
-#include <net-snmp/library/snmp_api.h>
++/* -------------------------------------------------------------------------- */
/*
* This is one element of an object identifier with either an integer
-@@ -138,8 +99,8 @@
+@@ -138,8 +92,8 @@
struct range_list *ranges;
} tclist[MAXTC];
@@ -116,7 +109,7 @@
static int anonymous = 0;
struct objgroup {
-@@ -4569,51 +4530,8 @@
+@@ -4569,51 +4523,8 @@
char token[MAXTOKEN], token2[MAXTOKEN];
char tmpstr[300];
int count = 0;
@@ -168,8 +161,8 @@
if ((dir = opendir(dirname))) {
snprintf(tmpstr, sizeof(tmpstr), "%s/.index", dirname);
---- parse.h.orig 2003-05-08 11:32:04.000000000
-+++ parse.h 2006-01-27 12:56:14.000000000
+--- parse.h.orig 2003-05-08 11:32:04.000000000
++++ parse.h 2006-01-27 12:56:14.000000000
@@ -119,11 +119,6 @@
struct varbind_list *varbinds;
char *hint;
diff --git a/mib/parse.c b/mib/parse.c
index aeb449f..0504599 100644
--- a/mib/parse.c
+++ b/mib/parse.c
@@ -69,16 +69,8 @@ SOFTWARE.
#include "parse.h"
-/*
- * A file with compatibility definitions for making the following
- * code work without the net-snmp library and all that.
- */
-#include "parse-compat.inc.c"
-
/* -------------------------------------------------------------------------- */
-
-
/*
* This is one element of an object identifier with either an integer
* subidentifier, or a textual string label, or both.