[ZBX-9793] SNMP Value has unknown type 0x78 for float value Created: 2015 Aug 19  Updated: 2017 May 30  Resolved: 2015 Oct 08

Status: Closed
Project: ZABBIX BUGS AND ISSUES
Component/s: Server (S)
Affects Version/s: 2.2.8
Fix Version/s: 2.2.11rc1, 2.4.7rc1, 3.0.0alpha3

Type: Incident report Priority: Major
Reporter: Andrei Gushchin (Inactive) Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: snmp, unknown
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File snmp-opaque-float.patch    
Issue Links:
Duplicate

 Description   

snmp items become unsupported with error *Value has unknown type 0x78

root@zabbix:/home/x# snmpwalk -v2c -c public x.x.x.x 1.3.6.1.4.1.7465.20.2.9.4.4.5.1.2.1.5.1.1
SNMPv2-SMI::enterprises.7465.20.2.9.4.4.5.1.2.1.5.1.1 = Opaque: Float: 0.000000

Network dump

zabbix.x.6972 > x.x.x.x.snmp: [bad udp cksum 0x1227 -> 0x530b!]  { SNMPv2c { GetRequest(39) R=1485401879  E:7465.20.2.9.4.4.5.1.2.1.5.1.1 } }
x.x.x.x.snmp > zabbix.x.6972: [udp sum ok]  { SNMPv2c { GetResponse(46) R=1485401879  E:7465.20.2.9.4.4.5.1.2.1.5.1.1=[P/A/Opaque]_9f_78_04_00_00_00_00 } }


 Comments   
Comment by Aleksandrs Saveljevs [ 2015 Aug 24 ]

In src/zabbix_server/poller/checks_snmp.c, we have the following code:

#ifdef OPAQUE_SPECIAL_TYPES
	else if (ASN_FLOAT == var->type)
	{
		SET_DBL_RESULT(result, *var->val.floatVal);
	}
	else if (ASN_DOUBLE == var->type)
	{
		SET_DBL_RESULT(result, *var->val.doubleVal);
	}
#endif

If we are compiled with OPAQUE_SPECIAL_TYPES, then, theoretically, opaque float should be supported.

Could you please check whether your server is compiled with OPAQUE_SPECIAL_TYPES? This can be checked, for instance, by inserting the following line after #if and trying to recompile:

#error OPAQUE_SPECIAL_TYPES is defined
Comment by Andrei Gushchin (Inactive) [ 2015 Sep 08 ]

Here is the output from stderr

checks_snmp.c: In function ?zbx_snmp_set_result?:
checks_snmp.c:594:2: error: #error OPAQUE_SPECIAL_TYPES is defined
make[3]: *** [libzbxpoller_a-checks_snmp.o] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all-recursive] Error 1
Comment by Aleksandrs Saveljevs [ 2015 Sep 08 ]

In checks_snmp.c, we check for "var->type" being ASN_FLOAT and ASN_DOUBLE. However, looking at Net-SNMP source code in snmplib/mib.c, it checks for ASN_OPAQUE_FLOAT and ASN_OPAQUE_DOUBLE instead. The value of ASN_FLOAT is 0x48, but the value of ASN_OPAQUE_FLOAT is 0x78, which is the type mentioned in the issue title.

Attached "snmp-opaque-float.patch" replaces ASN_FLOAT with ASN_OPAQUE_FLOAT and similarly for double. Could you please apply the patch and see whether that helps?

Comment by Aleksandrs Saveljevs [ 2015 Sep 14 ]

It was not explicitly stated here, but the patch seems to have helped.

Comment by Aleksandrs Saveljevs [ 2015 Sep 17 ]

I was looking for a way to set up an SNMP agent to return an opaque float (because we do not have the hardware that does it out of the box) and this is an attempt to document that research.

One of the most promising resources was https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sect-System_Monitoring_Tools-Net-SNMP-Extending.html , which talks about extending an agent and, in particular, doing that with Perl, like so:

elsif ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.1")) {
    $request->setValue(ASN_INTEGER, $integer_value);
}

In NetSNMP::ASN module, ASN_FLOAT is available. However, if we use ASN_FLOAT in the line above, we get the following error in /var/log/syslog, logged by snmpd:

unknown var value type: 72

Looking at the definition of setValue() at http://sourceforge.net/p/net-snmp/code/ci/master/tree/perl/agent/agent.xs , it can be seen that ASN_FLOAT is not supported (note also that in http://search.cpan.org/dist/NetSNMP-ASN-5.0401/ASN.pm there is no ASN_OPAQUE_FLOAT).

Another promising example was the "pass" command in snmpd.conf, which uses http://sourceforge.net/p/net-snmp/code/ci/master/tree/local/passtest.pl . Unfortunately, according to http://net-snmp.sourceforge.net/docs/man/snmpd.conf.html#lbAZ , only a restricted subset of types in available this way:

integer, gauge, counter, timeticks, ipaddress, objectid, or string

Then there is a theoretical discussion at http://sourceforge.net/p/net-snmp/mailman/message/17260104/ on how to transfer a floating point in SNMP:

The SNMP standard does not strictly include support for
non-integer numeric values. If you need to implement a
fractional value, there are three options:

a) Define the object as a fixed-point decimal value,
and use an INTEGER-based syntax (with an
implicit decimal point). For example, sysUpTime
is measured in "centiseconds", thus representing
a floating point value to two decimal places.

b) Use a String-based value to contain a printable version
of the value you wish to represent. The client application
would then need to parse this back into a floating point value.

c) Use the OPAQUE type to wrap the floating point value
in a form that can be transferred using SNMP. The client
library would then unwrap this to recover the original value.
This approach is used for the Net-SNMP syntax Float.
It works seamlessly for Net-SNMP-based applications, but
would typically not be recognised by any other SNMP toolkit.

See the MIB group UCD-SNMP-MIB::laTable for example of all
three of these approaches.

There is also a more practical discussion at http://marc.info/?l=net-snmp-users&m=108195420227564&w=2 and http://marc.info/?l=net-snmp-users&m=108195768211817&w=2 on how to make it available in C.

However, as mentioned above, it turns out that it is not necessary to add a new OID - an OID that returns an opaque float already exists in the default installation of snmpd:

$ snmpwalk -c public -v2c 127.0.0.1 laTable
UCD-SNMP-MIB::laIndex.1 = INTEGER: 1
UCD-SNMP-MIB::laIndex.2 = INTEGER: 2
UCD-SNMP-MIB::laIndex.3 = INTEGER: 3
UCD-SNMP-MIB::laNames.1 = STRING: Load-1
UCD-SNMP-MIB::laNames.2 = STRING: Load-5
UCD-SNMP-MIB::laNames.3 = STRING: Load-15
UCD-SNMP-MIB::laLoad.1 = STRING: 0.02
UCD-SNMP-MIB::laLoad.2 = STRING: 0.11
UCD-SNMP-MIB::laLoad.3 = STRING: 0.18
UCD-SNMP-MIB::laConfig.1 = STRING: 12.00
UCD-SNMP-MIB::laConfig.2 = STRING: 10.00
UCD-SNMP-MIB::laConfig.3 = STRING: 5.00
UCD-SNMP-MIB::laLoadInt.1 = INTEGER: 2
UCD-SNMP-MIB::laLoadInt.2 = INTEGER: 11
UCD-SNMP-MIB::laLoadInt.3 = INTEGER: 18
UCD-SNMP-MIB::laLoadFloat.1 = Opaque: Float: 0.020000
UCD-SNMP-MIB::laLoadFloat.2 = Opaque: Float: 0.110000
UCD-SNMP-MIB::laLoadFloat.3 = Opaque: Float: 0.180000
UCD-SNMP-MIB::laErrorFlag.1 = INTEGER: noError(0)
UCD-SNMP-MIB::laErrorFlag.2 = INTEGER: noError(0)
UCD-SNMP-MIB::laErrorFlag.3 = INTEGER: noError(0)
UCD-SNMP-MIB::laErrMessage.1 = STRING: 
UCD-SNMP-MIB::laErrMessage.2 = STRING: 
UCD-SNMP-MIB::laErrMessage.3 = STRING:

The way it is implemented internally seems to be at http://sourceforge.net/p/net-snmp/code/ci/master/tree/agent/mibgroup/ucd-snmp/loadave.c .

Comment by Aleksandrs Saveljevs [ 2015 Sep 17 ]

Fixed in development branch svn://svn.zabbix.com/branches/dev/ZBX-9793 .

The fix replaces ASN_FLOAT with ASN_OPAQUE_FLOAT and ASN_DOUBLE with ASN_OPAQUE_DOUBLE, as in the patch. However, it also additionally replaces ASN_UNSIGNED64 with ASN_OPAQUE_U64 and ASN_INTEGER64 with ASN_OPAQUE_I64, because the former are not used (with one exception) in Net-SNMP source code. Finally, it adds support for ASN_OPAQUE_COUNTER64, in addition to the already working ASN_COUNTER64.

Comment by Andris Zeila [ 2015 Sep 28 ]

Successfully tested

Comment by Aleksandrs Saveljevs [ 2015 Sep 28 ]

Fixed in pre-2.2.11 r55793, pre-2.4.7 r55794, pre-3.0.0alpha3 (trunk) r55795.

Generated at Thu Apr 25 22:24:38 EEST 2024 using Jira 9.12.4#9120004-sha1:625303b708afdb767e17cb2838290c41888e9ff0.