Fix for perl subagent counter64 (was Re: Net-snmp master agentx not speaking the same protocol as a perl subagent?)

"Brice Figureau" <[email protected]>
Newsgroups gmane.network.net-snmp.user
Message-ID <[email protected]>
Hi,

On Sun, July 20, 2008 18:18, Brice Figureau wrote:
> I'm developing a perl agentx subagent for net-snmp 5.4.1.
> The mib that this agent is handling contains a few Counter64 (which are
> not correctly handled by the perl agent, but that's not my main issue).
> The first counter64 is enterprises.20267.200.1.6.0. The rest is either
> gauge or counter32.
>
> The problem is the following:
>
> the enterprises.20267.200.1.6.0 oid is a counter64 (whose vallue size is <
> 32bits).
> When requesting this value from snmpwalk, snmpget, snmpbulkwalk or
> snmpbulkget in v2c mode, the right value is returned:
>
> snmpbulkget -r1 -Cn1 -Cr0 -v 2c -c public 192.168.168.14
> .1.3.6.1.4.1.20267.200.1.6
> SNMPv2-SMI::enterprises.20267.200.1.6.0 = Counter64: 3095605758
>
> (in this example, I patched agent.xs to be able to feed a struct counter64
> to snmp_set_var_typed_value to get the real result, otherwise the high and
> low part of the counter where swapped on amd64/i386).

Here is a patch against current SVN head that fixes the counter64 handling
in perl subagent for 32bits and 64bits arch (tested on i386 and x86_64
only).

Thanks,
-- 
Brice Figureau

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
fix-perl-subagent-counter64.patch (application/octet-stream, 2.6 KB)
IIndex: perl/agent/agent.xs
===================================================================
--- perl/agent/agent.xs	(revision 17116)
+++ perl/agent/agent.xs	(working copy)
@@ -773,6 +773,8 @@
         netsnmp_request_info *request;
         u_long utmp;
         long ltmp;
+        unsigned long long ulltmp;
+        struct counter64 c64;
 	oid myoid[MAX_OID_LEN];
 	size_t myoid_len;
         STRLEN stringlen;
@@ -828,7 +830,6 @@
 
           case ASN_UNSIGNED:
           case ASN_COUNTER:
-          case ASN_COUNTER64:
           case ASN_TIMETICKS:
 	      /* We want an integer here */
 	      if ((SvTYPE(value) == SVt_IV) || (SvTYPE(value) == SVt_PVMG) ||
@@ -862,6 +863,41 @@
 		break;
 	      }
 
+          case ASN_COUNTER64:
+              /* We want an integer here */
+              if ((SvTYPE(value) == SVt_IV) || (SvTYPE(value) == SVt_PVMG)) {
+                  /* Good - got a real one (or a blessed scalar which we have to hope will turn out OK) */
+                  ulltmp = SvIV(value);
+                  c64.high = (ulltmp & 0xffffffff00000000ULL) >> 32;
+                  c64.low = ulltmp & 0xffffffffULL;
+                  snmp_set_var_typed_value(request->requestvb, (u_char)type,
+                                       (u_char *) &c64, sizeof(struct counter64));
+                  RETVAL = 1;
+                  break;
+              }
+              else if (SvPOKp(value)) {
+                  /* Might be OK - got a string, so try to convert it, allowing base 10, octal, and hex forms */
+                  stringptr = SvPV(value, stringlen);
+                  ulltmp = strtoull( stringptr, NULL, 0 );
+                  if (errno == EINVAL) {
+                        snmp_log(LOG_ERR, "Could not convert string to number in setValue: '%s'", stringptr);
+                        RETVAL = 0;
+                        break;
+                  }
+                  c64.high = (ulltmp & 0xffffffff00000000ULL) >> 32;
+                  c64.low = ulltmp & 0xffffffffULL;
+                  snmp_set_var_typed_value(request->requestvb, (u_char)type,
+                                       (u_char *) &c64, sizeof(struct counter64));
+                  RETVAL = 1;
+                  break;
+              }
+              else {
+                snmp_log(LOG_ERR, "Non-unsigned-integer value passed to setValue with ASN_COUNTER64: type was %d",
+                        SvTYPE(value));
+                RETVAL = 0;
+                break;
+              }
+
           case ASN_OCTET_STR:
           case ASN_BIT_STR:
 	      /* Check that we have been passed something with a string value (or a blessed scalar) */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.