[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