[Xymon] More patches for SNMP processing
Brian Scott
bscott at bunyatech.com.au
Wed Jul 14 14:09:06 CEST 2021
Hi List,
Having now completed my investigation into SNMP handling in Xymon, I
have some more changes to propose. Basically, this change introduces an
extra method for finding indexes in SNMP tables when nothing that is
provided is unique.
I've also allowed for negative values and decimal points in returned
data since both seemed to happen very quickly for me (no, the negative
values weren't an error - they were wireless signal strengths).
I have some documentation updates in progress to try and fill some of
the holes in this area. I send them soon.
Cheers,
Brian Scott
-------------- next part --------------
--- lib/readmib.c.orig 2019-07-24 01:29:06.000000000 +1000
+++ lib/readmib.c 2021-07-11 13:36:18.763973000 +1000
@@ -148,18 +148,19 @@
continue;
}
- if (mib && ((strncmp(bot, "keyidx", 6) == 0) || (strncmp(bot, "validx", 6) == 0))) {
+ if (mib && ((strncmp(bot, "keyidx", 6) == 0) || (strncmp(bot, "validx", 6) == 0) || (strncmp(bot, "idxidx", 6) == 0))) {
/*
* Define an index. Looks like:
* keyidx (IF-MIB::ifDescr)
* validx [IP-MIB::ipAdEntIfIndex]
+ * idxidx (IF-MIB::ifDescr)
*/
char endmarks[6];
mibidx_t *newidx = (mibidx_t *)calloc(1, sizeof(mibidx_t));
p = bot + 6; p += strspn(p, " \t");
newidx->marker = *p; p++;
- newidx->idxtype = (strncmp(bot, "keyidx", 6) == 0) ? MIB_INDEX_IN_OID : MIB_INDEX_IN_VALUE;
+ newidx->idxtype = (strncmp(bot, "keyidx", 6) == 0) ? MIB_INDEX_IN_OID : (strncmp(bot, "validx", 6) == 0) ? MIB_INDEX_IN_VALUE : MIB_INDEX_IN_INDEX;
newidx->keyoid = strdup(p);
snprintf(endmarks, sizeof(endmarks), "%s%c", ")]}>", newidx->marker);
p = newidx->keyoid + strcspn(newidx->keyoid, endmarks); *p = '\0';
-------------- next part --------------
--- lib/readmib.h.orig 2013-07-23 22:20:59.000000000 +1000
+++ lib/readmib.h 2021-07-11 13:35:58.263924000 +1000
@@ -55,11 +55,18 @@
* is then the part of the key-OID beyond the base key table OID.
*/
- MIB_INDEX_IN_VALUE /*
+ MIB_INDEX_IN_VALUE, /*
* Index can be found by adding the key value as a part-OID to the
* base OID of the key (e.g. interfaces by IP-address).
* IP-MIB::ipAdEntIfIndex.127.0.0.1 = INTEGER: 1
* IP-MIB::ipAdEntIfIndex.172.16.10.100 = INTEGER: 3
+ */
+ MIB_INDEX_IN_INDEX /*
+ * Like _IN_OID but we aren't using a key, or rather we ar synthesising a
+ * key from the OID.
+ * IF-MIB::ifMtu.1 = INTEGER: 1500
+ * IF-MIB::ifMtu.2 = INTEGER: 1500
+ * The value has nothing useful as key.
*/
};
-------------- next part --------------
--- xymond/rrd/do_snmpmib.c.orig 2012-07-23 21:47:20.000000000 +1000
+++ xymond/rrd/do_snmpmib.c 2021-07-11 12:14:51.784743000 +1000
@@ -160,7 +160,7 @@
for (validx = 0; (params->valnames[validx] && strcmp(params->valnames[validx], valnam)); validx++) ;
/* Note: There may be items which are not RRD data (eg text strings) */
if (params->valnames[validx]) {
- values[validx] = (isdigit(*valstr) ? valstr : "U");
+ values[validx] = (isdigit(*valstr) || *valstr == '.' || *valstr == '-' ? valstr : "U");
valcount++;
}
}
-------------- next part --------------
--- xymonnet/xymon-snmpcollect.c.orig 2019-07-24 01:29:06.000000000 +1000
+++ xymonnet/xymon-snmpcollect.c 2021-07-11 16:08:21.964638000 +1000
@@ -180,6 +180,25 @@
done = 1;
}
break;
+
+ case MIB_INDEX_IN_INDEX:
+ dbgprintf("Doing INDEX_IN_INDEX kwalk->key = '%s'\n",kwalk->key);
+ if (*kwalk->key == '*') {
+ keyrecord_t *newkey;
+ newkey = (keyrecord_t *)calloc(1, sizeof(keyrecord_t));
+ memcpy(newkey, kwalk, sizeof(keyrecord_t));
+ newkey->indexoid = strdup(oidstr + keyoidlen + 1);
+ newkey->key = newkey->indexoid;
+ newkey->next = kwalk->next;
+ kwalk->next = newkey;
+ done = 1;
+ }
+ else if ((*(oidstr+keyoidlen) == '.') && (strcmp(oidstr+keyoidlen+1, kwalk->key)) == 0) {
+ /* Grab the index part of the OID */
+ kwalk->indexoid = strdup(oidstr + keyoidlen + 1);
+ done = 1;
+ }
+ break;
case MIB_INDEX_IN_VALUE:
/* Does the key match the index-part of the result OID? */
@@ -268,7 +287,8 @@
struct variable_list *vp = pdu->variables;
okoid = ((vp->name_length >= req->currentkey->indexmethod->rootoidlen) &&
- (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0));
+ (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0) &&
+ (vp->type != SNMP_ENDOFMIBVIEW) && (vp->type != SNMP_NOSUCHOBJECT) && (vp->type != SNMP_NOSUCHINSTANCE));
}
switch (pdu->errstat) {
@@ -278,7 +298,7 @@
break;
case SNMP_ERR_NOSUCHNAME:
- dbgprintf("Host %s item %s: No such name\n", req->hostname, req->curr_oid->devname);
+ dbgprintf("Host %s item %s: No such name\n", req->hostname, req->curr_oid ? req->curr_oid->devname : "*NULL");
if (req->hostip[req->hostipidx+1]) {
req->hostipidx++;
startonehost(req, 1);
@@ -308,14 +328,17 @@
struct variable_list *vp = pdu->variables;
if ( (vp->name_length >= req->currentkey->indexmethod->rootoidlen) &&
- (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0) ) {
+ (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0) &&
+ (vp->type != SNMP_ENDOFMIBVIEW) && (vp->type != SNMP_NOSUCHOBJECT) && (vp->type != SNMP_NOSUCHINSTANCE)) {
/* Still more data in the current key table, get the next row */
snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT);
pducount++;
/* Probably only one variable to fetch, but never mind ... */
while (vp) {
- varcount++;
- snmp_add_null_var(snmpreq, vp->name, vp->name_length);
+ if ((vp->type != SNMP_ENDOFMIBVIEW) && (vp->type != SNMP_NOSUCHOBJECT) && (vp->type != SNMP_NOSUCHINSTANCE)) {
+ varcount++;
+ snmp_add_null_var(snmpreq, vp->name, vp->name_length);
+ }
vp = vp->next_variable;
}
}
@@ -1090,7 +1113,7 @@
readmibs(NULL, mibcheck);
if (configfn == NULL) {
- configfn = (char *)malloc(PATH_MAX);
+ SBUF_MALLOC(configfn, PATH_MAX);
snprintf(configfn, configfn_buflen, "%s/etc/snmphosts.cfg", xgetenv("XYMONHOME"));
}
readconfig(configfn, mibcheck);
More information about the Xymon
mailing list